Merge pull request #271 from Techwolfy/upstream-new-comics-4

Upstream new comics 4
This commit is contained in:
Tobias Gruetzmacher 2023-06-09 15:49:03 +02:00 committed by GitHub
commit 02718209ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 236 additions and 214 deletions

View file

@ -6,7 +6,7 @@
from re import compile, escape, MULTILINE
from ..util import tagre
from ..scraper import BasicScraper, _BasicScraper, _ParserScraper
from ..scraper import BasicScraper, ParserScraper, _BasicScraper, _ParserScraper
from ..helpers import regexNamer, bounceStarter, indirectStarter
from .common import WordPressScraper, WordPressNavi, WordPressWebcomic
@ -166,18 +166,18 @@ class AllTheGrowingThings(WordPressScraper):
endOfLife = True
class AlphaLuna(_ParserScraper):
url = 'https://alphaluna.net/'
class AlphaLuna(ParserScraper):
url = 'https://alphalunacomic.net/'
stripUrl = url + 'comic/%s/'
firstStripUrl = stripUrl % 'issue-1-cover'
imageSearch = '//main[@id="comic"]//img'
prevSearch = '//a[@rel="prev"]'
class AlphaLunaSpanish(_ParserScraper):
class AlphaLunaSpanish(ParserScraper):
name = 'AlphaLuna/Spanish'
lang = 'es'
url = 'https://alphaluna.net/spanish/'
url = 'https://alphalunacomic.net/spanish/'
stripUrl = url + 'comic/%s/'
firstStripUrl = stripUrl % 'issue-1-cover'
imageSearch = '//main[@id="comic"]//img'

View file

@ -117,13 +117,6 @@ class CatAndGirl(_ParserScraper):
prevSearch = '//a[d:class("pager--prev")]'
class CatenaCafe(WordPressScraper):
name = 'CatenaManor/CatenaCafe'
url = 'https://catenamanor.com/'
stripUrl = url + 'comic/%s/'
firstStripUrl = stripUrl % 'reboot-book1cover-small'
class CatenaManor(_ParserScraper):
baseUrl = ('https://web.archive.org/web/20141027141116/'
'http://catenamanor.com/')

View file

@ -73,10 +73,16 @@ class ComicFury(ParserScraper):
'//img[d:class("comicsegmentimage")]',
)
def namer(self, image_url, page_url):
parts = page_url.split('/')
path, ext = os.path.splitext(image_url)
def namer(self, imageUrl, pageUrl):
parts = pageUrl.split('/')
path, ext = os.path.splitext(imageUrl)
num = parts[-1]
if self.multipleImagesPerStrip:
page = self.getPage(pageUrl)
images = page.xpath('//img[@class="comicsegmentimage"]/@src')
if len(images) > 1:
imageIndex = images.index(imageUrl) + 1
return "%s_%s-%d%s" % (self.prefix, num, imageIndex, ext)
return "%s_%s%s" % (self.prefix, num, ext)
def shouldSkipUrl(self, url, data):
@ -136,7 +142,7 @@ class ComicFury(ParserScraper):
cls('AgentBishop', 'agentbishop'),
cls('AHappierKindOfSad', 'ahappierkindofsad'),
cls('AlbinoBrothers', 'albinobros'),
cls('Alderwood', 'alderwood'),
cls('Alderwood', 'alderwood', segmented=True),
cls('AlexanderAndLucasRebooted', 'alexanderandlucas'),
cls('AliaTerra', 'alia-terra'),
cls('AlienIrony', 'alien-irony'),
@ -785,6 +791,7 @@ class ComicFury(ParserScraper):
cls('Pulse', 'pulse'),
cls('PureHavoc', 'pure-havoc'),
cls('Queenie', 'queenie'),
cls('QueenieAdventure', 'queenieadventure', adult=True, segmented=True),
cls('QuestCorporeal', 'questcorporeal'),
cls('Rain', 'rain'),
cls('RandomlyAssembled', 'randomlyassembled'),

View file

@ -6,7 +6,7 @@
from re import compile, escape
from ..util import tagre
from ..scraper import _BasicScraper, _ParserScraper
from ..scraper import ParserScraper, _BasicScraper, _ParserScraper
from ..helpers import indirectStarter, joinPathPartsNamer
from .common import ComicControlScraper, WordPressNaviIn, WordPressScraper
@ -20,24 +20,6 @@ class FalconTwin(_BasicScraper):
help = 'Index format: nnn'
class FalseStart(_ParserScraper):
baseUrl = 'https://boneitisindustries.com/'
url = baseUrl + 'comics/false-start/'
stripUrl = baseUrl + 'comic/%s/'
firstStripUrl = stripUrl % 'false-start-chapter-zero-page-1'
imageSearch = '//div[@id="content"]//img[d:class("size-full")]'
prevSearch = '//a[./span[d:class("ticon-chevron-left")]]'
adult = True
def starter(self):
archivePage = self.getPage(self.url)
self.archive = archivePage.xpath('//div[contains(@class, "vcex-portfolio-grid")]//a/@href')
return self.archive[-1]
def getPrevUrl(self, url, data):
return self.archive[self.archive.index(url) - 1]
class Faneurysm(WordPressNaviIn):
url = 'http://hijinksensue.com/comic/think-only-tree/'
firstStripUrl = 'http://hijinksensue.com/comic/captains-prerogative/'
@ -149,18 +131,19 @@ class ForLackOfABetterComic(_ParserScraper):
endOfLife = True
class FoxDad(_ParserScraper):
class FoxDad(ParserScraper):
url = 'https://foxdad.com/'
stripUrl = url + 'post/%s'
firstStripUrl = stripUrl % '149683014997/some-people-are-just-different-support-the-comic'
imageSearch = ('//figure[@class="photo-hires-item"]//img', '//figure[@class="tmblr-full"]//img')
imageSearch = '//figure[@class="photo-hires-item"]//img'
prevSearch = '//a[@class="previous-button"]'
def namer(self, imageUrl, pageUrl):
page = self.getPage(pageUrl)
post = page.xpath('//link[@type="application/json+oembed"]')[0].get('href')
post = post.replace('https://www.tumblr.com/oembed/1.0?url=https://foxdad.com/post', '')
post = post.replace('-support-me-on-patreon', '')
post = page.xpath('//li[@class="timestamp"]/a/@href')[0]
post = post.replace('https://foxdad.com/post/', '')
if '-consider-support' in post:
post = post.split('-consider-support')[0]
return post.replace('/', '-')

View file

@ -59,16 +59,6 @@ class GeeksNextDoor(_ParserScraper):
help = 'Index format: yyyy-mm-dd'
class Ginpu(WordPressNavi):
url = 'https://www.ginpu.us/'
stripUrl = url + 'comic/%s/'
firstStripUrl = stripUrl % 'filler-2'
def namer(self, imageUrl, pageUrl):
filename = imageUrl.rsplit('/', 3)
return '%s-%s_%s' % (filename[1], filename[2], filename[3])
class GirlGenius(_BasicScraper):
baseUrl = 'http://www.girlgeniusonline.com/'
rurl = escape(baseUrl)

View file

@ -68,6 +68,20 @@ class HeadlessBliss(ComicControlScraper):
url = 'http://headlessbliss.com/'
class Hellkats(ParserScraper):
url = 'https://poecatcomix.com/hellkatscomic/'
stripUrl = url + '%s/'
firstStripUrl = stripUrl % 'hellkats-issue-1-cover'
imageSearch = '//img[@class="scale-with-grid wp-post-image"]'
prevSearch = '//a[d:class("fixed-nav-prev")]'
latestSearch = '//div[@class="post-title"]//a'
starter = indirectStarter
adult = True
def namer(self, imageUrl, pageUrl):
return pageUrl.rsplit('/', 2)[1] + '.' + imageUrl.rsplit('.', 1)[-1]
class HeyFox(WordPressScraper):
url = 'http://www.steamclaw.com/heyfox/'
stripUrl = url + 'archives/comic/%s'

View file

@ -41,6 +41,16 @@ class InternetWebcomic(WordPressNavi):
help = 'Index format: n'
class Inverloch(ParserScraper):
stripUrl = 'https://www.seraph-inn.com/view.php?story=inverloch&page=%s'
url = stripUrl % '763'
firstStripUrl = stripUrl % '2'
imageSearch = '//img[@class="page"]'
prevSearch = '//p[@class="comic-nav"]/a[text()=" Previous"]'
multipleImagesPerStrip = True
endOfLife = True
class IrregularWebcomic(BasicScraper):
url = 'http://www.irregularwebcomic.net/'
stripUrl = url + '%s.html'

View file

@ -37,11 +37,17 @@ class KemonoCafe(ParserScraper):
filename = filename.replace('89', '90')
elif 'rascals' in pageUrl and '133-2' in pageUrl:
filename = filename.replace('133', '134')
elif 'caughtinorbit' in pageUrl and '26gs' in filename:
filename = filename.replace('026gs', '021')
elif 'caughtinorbit' in pageUrl and '27gs' in filename:
filename = filename.replace('027gs', '022')
# Fix unordered filenames
if 'addictivescience' in pageUrl:
page = self.getPage(pageUrl)
num = int(page.xpath('//div[@id="comic-wrap"]/@class')[0].replace('comic-id-', ''))
filename = '%04d_%s' % (num, filename)
elif 'CaughtInOrbit' in filename:
filename = filename.replace('CaughtInOrbit', 'CIO')
return filename
@classmethod
@ -50,13 +56,13 @@ class KemonoCafe(ParserScraper):
cls('AddictiveScience', 'addictivescience', 'page0001'),
cls('Bethellium', 'bethellium', 'c01p00'),
cls('CaribbeanBlue', 'cb', 'page000', last='page325'),
cls('CaughtInOrbit', 'caughtinorbit', 'comic-cover'),
cls('IMew', 'imew', 'imew00', last='imew50'),
cls('Knighthood', 'knighthood', 'kh0001'),
cls('KnuckleUp', 'knuckle-up', 'page001', adult=True),
cls('LasLindas', 'laslindas', 'll0001', adult=True),
cls('Paprika', 'paprika', 'page000'),
cls('PracticeMakesPerfect', 'pmp', 'title-001'),
cls('PrincessBunny', 'princessbunny', 'pg001'),
cls('Rascals', 'rascals', 'rascals-pg-0', adult=True),
cls('TheEyeOfRamalach', 'theeye', 'theeye-page01'),
cls('TinaOfTheSouth', 'tots', 'tos-01-01'),

View file

@ -11,11 +11,11 @@ from ..util import tagre
from .common import ComicControlScraper, WordPressScraper, WordPressNaviIn
class Lackadaisy(_ParserScraper):
class Lackadaisy(ParserScraper):
url = 'https://www.lackadaisy.com/comic.php'
stripUrl = url + '?comicid=%s'
firstStripUrl = stripUrl % '1'
imageSearch = '//div[@id="content"]/img'
imageSearch = '//div[@id="exhibit"]/img[contains(@src, "comic/")]'
prevSearch = '//div[@class="prev"]/a'
nextSearch = '//div[@class="next"]/a'
help = 'Index format: n'
@ -28,6 +28,12 @@ class Lackadaisy(_ParserScraper):
return 'lackadaisy_%s.%s' % (num, ext)
class Lancer(WordPressScraper):
url = 'https://lancercomic.com/'
stripUrl = url + 'comic/%s/'
firstStripUrl = stripUrl % 'chapter-1-cover'
class LastResort(WordPressScraper):
url = 'http://www.lastres0rt.com/'
stripUrl = url + 'comic/%s/'

View file

@ -95,6 +95,8 @@ class MangaDex(ParserScraper):
@classmethod
def getmodules(cls):
return (
cls('AniTomo', '920c22e7-49c9-4bb4-b394-0c964b6037fc'),
cls('ArcaneSniper', 'cbf53f02-9594-42e7-9dbf-8ae1c783466f'),
cls('AttackOnTitan', '304ceac3-8cdb-4fe7-acf7-2b6ff7a60613'),
cls('Beastars', 'f5e3baad-3cd4-427c-a2ec-ad7d776b370d'),
cls('BokuNoKokoroNoYabaiYatsu', '3df1a9a3-a1be-47a3-9e90-9b3e55b1d0ac'),
@ -104,6 +106,7 @@ class MangaDex(ParserScraper):
cls('DragonDrive', '5c06ae70-b5cf-431a-bcd5-262a411de527'),
cls('FuguushokuKajishiDakedoSaikyouDesu', '17b3b648-fd89-4a69-9a42-6068ffbfa7a7'),
cls('GanbareDoukiChan', '190616bc-7da6-45fd-abd4-dd2ca656c183'),
cls('GijiHarem', 'd8f9afe2-aa44-4bc6-9145-eebb1f282372'),
cls('HangingOutWithAGamerGirl', 'de9e3b62-eac5-4c0a-917d-ffccad694381'),
cls('HoriMiya', 'a25e46ec-30f7-4db6-89df-cacbc1d9a900'),
cls('HowToOpenATriangularRiceball', '6ebd90ce-d5e8-49c0-a4bc-e02e0f8ecb93'),
@ -113,17 +116,23 @@ class MangaDex(ParserScraper):
cls('JahySamaWaKujikenai', '2f4e5f5b-d930-4266-8c8a-c4cf9a81e51f'),
cls('JingaiNoYomeToIchaIchaSuru', '809d2493-df3c-4e72-a57e-3e0026cae9fb'),
cls('KaetteKudasaiAkutsuSan', '737a846b-2e67-4d63-9f7e-f54b3beebac4'),
cls('KaikoSaretaAnkokuHeishi30DaiNoSlowNaSecondLife', 'cbcf5051-74a0-4b93-b99c-1a6975f1bef9'),
cls('KawaiiJoushiWoKomarasetai', '23b7cc7a-df89-4049-af28-1fa78f88713e'),
cls('KanojoOkarishimasu', '32fdfe9b-6e11-4a13-9e36-dcd8ea77b4e4'),
cls('KoiToUtatane', 'f7d40a27-e289-45b3-9c68-d1cb251897e6'),
cls('KonoKaishaNiSukiNaHitoGaImasu', '3e8cf40f-ba17-480a-b60b-a675db032ee2'),
cls('LonelyGirlNiSakaraenai', 'd7576e72-0301-4ed3-9137-722ed768bfda'),
cls('Lv2KaraCheatDattaMotoYuushaKouhoNoMattariIsekaiLife', '58bc83a0-1808-484e-88b9-17e167469e23'),
cls('MaouNoOreGaDoreiElfWoYomeNiShitandaGaDouMederebaIi', '55ace2fb-e157-4d76-9e72-67c6bd762a39'),
cls('ModernMoGal', 'b1953f80-36f7-492c-b0f8-e9dd0ad01752'),
cls('MousouTelepathy', '3d25d7da-893f-400e-9aeb-6163773c671a'),
cls('MyTinySenpaiFromWork', '28ed63af-61f8-43af-bac3-762030c72963'),
cls('MyWifeIsFromAThousandYearsAgo', '17a56d33-9443-433a-9e0d-70459893ed8f'),
cls('OMaidensinYourSavageSeason', 'c4613b7d-7a6e-48f9-82f0-bce3dd33383a'),
cls('OokamiShounenWaKyouMoUsoOKasaneru', '5e77d9e2-2e44-431a-a995-5fefd411e55e'),
cls('OokamiToKoshinryou', 'de900fd3-c94c-4148-bbcb-ca56eaeb57a4'),
cls('OtomeYoukaiZakuro', 'c1fa97be-0f1f-4686-84bc-806881c97d53'),
cls('Overgeared', '3fc308c9-4b00-4dc3-943e-1f39242bc708'),
cls('OversimplifiedSCP', 'e911fe33-a9b3-43dc-9eb7-f5ee081a6dc8'),
cls('PashiriNaBokuToKoisuruBanchouSan', '838e5b3a-51c8-44cf-b6e2-68193416f6fe'),
cls('PleaseDontBullyMeNagatoro', 'd86cf65b-5f6c-437d-a0af-19a31f94ec55'),
@ -141,12 +150,14 @@ class MangaDex(ParserScraper):
cls('SwordArtOnlineProgressive', '22ea3f54-11e4-4932-a527-89d63d3a62d9'),
cls('TadokoroSan', '8ffbfa2f-23fa-4490-848e-942581a4d873'),
cls('TamenDeGushi', '3f1453fb-9dac-4aca-a2ea-69613856c952'),
cls('TamingMaster', '534c1b5b-aff6-44fd-bf68-7294e6526fb3'),
cls('TenseiShitaraSlimeDattaKen', 'e78a489b-6632-4d61-b00b-5206f5b8b22b'),
cls('TheNewGate', 'b41bef1e-7df9-4255-bd82-ecf570fec566'),
cls('TheWolfAndRedRidingHood', 'a7d1283b-ed38-4659-b8bc-47bfca5ccb8a'),
cls('TomoChanWaOnnanoko', '76ee7069-23b4-493c-bc44-34ccbf3051a8'),
cls('TonikakuKawaii', '30f3ac69-21b6-45ad-a110-d011b7aaadaa'),
cls('UramikoiKoiUramikoi', '009b6788-48f3-4e78-975c-097f54def7ab'),
cls('UzakiChanWaAsobitai', '5a90308a-8b12-4a4d-9c6d-2487028fe319'),
cls('YotsubaAnd', '58be6aa6-06cb-4ca5-bd20-f1392ce451fb'),
cls('YuYuHakusho', '44a5cbe1-0204-4cc7-a1ff-0fda2ac004b6'),
)

View file

@ -5,7 +5,7 @@
# Copyright (C) 2019-2020 Daniel Ring
from re import compile, escape
from ..scraper import _BasicScraper, _ParserScraper
from ..scraper import ParserScraper, _BasicScraper, _ParserScraper
from ..helpers import indirectStarter, bounceStarter
from ..util import tagre
from .common import ComicControlScraper, WordPressScraper, WordPressNavi, WordPressWebcomic
@ -113,29 +113,18 @@ class Nicky510(WordPressNavi):
endOfLife = True
class Nightshift(WordPressWebcomic):
url = 'https://poecatcomix.com/nightshift-static/'
stripUrl = 'https://poecatcomix.com/nightshift/%s/'
firstStripUrl = stripUrl % 'ns-cover'
imageSearch = '//div[contains(@class, "webcomic-media")]//img'
class Nightshift(ParserScraper):
url = 'https://poecatcomix.com/nightshiftcomic/'
stripUrl = url + '%s/'
firstStripUrl = stripUrl % 'ns-issue-1-cover'
imageSearch = '//img[@class="scale-with-grid wp-post-image"]'
prevSearch = '//a[d:class("fixed-nav-prev")]'
latestSearch = '//div[@class="post-title"]//a'
starter = indirectStarter
adult = True
def starter(self):
# Build list of chapters for naming
indexPage = self.getPage(self.url)
self.chapters = indexPage.xpath('//a[./img[contains(@class, "attachment-large")]]/@href')
latestPage = self.chapters[0]
self.chapters = self.chapters[1:]
self.currentChapter = len(self.chapters)
return latestPage
def namer(self, imageUrl, pageUrl):
page = pageUrl.rstrip('/').rsplit('/', 1)[-1]
page = page.replace('blood-brothers', 'bloodbrothers').replace('bb-2', 'bb2').replace('ns7-', 'page-')
filename = 'ns%d-%s.%s' % (self.currentChapter, page, imageUrl.rsplit('.', 1)[-1])
if pageUrl in self.chapters:
self.currentChapter = self.currentChapter - 1
return filename
return pageUrl.rsplit('/', 2)[1] + '.' + imageUrl.rsplit('.', 1)[-1]
class Nimona(_ParserScraper):
@ -176,13 +165,13 @@ class NoNeedForBushido(_ParserScraper):
help = 'Index format: nnn'
class NonPlayerCharacter(_ParserScraper):
class NonPlayerCharacter(ParserScraper):
url = 'https://www.lfg.co/'
stripUrl = url + 'npc/tale/%s/'
stripUrl = url + 'npc/comic/%s/'
firstStripUrl = stripUrl % '1-1'
imageSearch = '//div[@id="comic-img"]//img'
prevSearch = '//a[@class="comic-nav-prev"]'
latestSearch = '//div[@id="feature-npc-footer"]/a[contains(@href, "npc/tale/")]'
latestSearch = '//div[@id="feature-npc-footer"]/a[contains(@href, "npc/comic/")]'
starter = indirectStarter
def namer(self, imageUrl, pageUrl):

View file

@ -75,6 +75,7 @@ class OhJoySexToy(WordPressNavi):
url = 'http://www.ohjoysextoy.com/'
firstStripUrl = url + 'introduction/'
textSearch = '//div[@id="comic"]//img/@alt'
multipleImagesPerStrip = True
adult = True

View file

@ -604,6 +604,7 @@ class Removed(Scraper):
cls('WotNow'),
# Removed in 3.0
cls('CatenaManor/CatenaCafe'),
cls('ComicFury/AdventuresOftheGreatCaptainMaggieandCrew'),
cls('ComicFury/AWAKENING'),
cls('ComicFury/Beebleville'),
@ -832,6 +833,8 @@ class Removed(Scraper):
cls('ComicsKingdom/Redeye'),
cls('ComicsKingdom/RedeyeSundays'),
cls('CrapIDrewOnMyLunchBreak'),
cls('FalseStart'),
cls('Ginpu'),
cls('GoComics/060'),
cls('GoComics/2CowsAndAChicken'),
cls('GoComics/ABitSketch'),
@ -992,9 +995,11 @@ class Removed(Scraper):
cls('GoComics/Wrobbertcartoons'),
cls('GoComics/Zootopia'),
cls('JustAnotherEscape'),
cls('KemonoCafe/PrincessBunny'),
cls('Laiyu', 'brk'),
cls('MangaDex/DrStone', 'legal'),
cls('MangaDex/HeavensDesignTeam', 'legal'),
cls('MangaDex/ImTheMaxLevelNewbie', 'legal'),
cls('MangaDex/SPYxFAMILY', 'legal'),
cls('Ryugou'),
cls('SeelPeel'),
@ -1568,16 +1573,21 @@ class Removed(Scraper):
cls('SnafuComics/Tin'),
cls('SnafuComics/Titan'),
cls('StudioKhimera/Eorah', 'mov'),
cls('StudioKhimera/Mousechevious'),
cls('StuffNoOneToldMe'),
cls('TaleOfTenThousand'),
cls('TalesAndTactics'),
cls('TheCyantianChronicles/CookieCaper'),
cls('TheCyantianChronicles/Pawprints'),
cls('VampireHunterBoyfriends'),
cls('VGCats/Adventure'),
cls('VGCats/Super'),
cls('VictimsOfTheSystem'),
cls('WebDesignerCOTW'),
cls('WebToons/Adamsville'),
cls('WebToons/CrapIDrewOnMyLunchBreak'),
cls('WebToons/CrystalVirus'),
cls('WebToons/OVERPOWERED'),
cls('WintersLight'),
)
@ -1679,6 +1689,7 @@ class Renamed(Scraper):
cls('SmackJeeves/TheRealmOfKaerwyn', 'ComicFury/TheRealmOfKaerwyn'),
cls('SoloLeveling', 'MangaDex/SoloLeveling'),
cls('StudioKhimera/Draconia', 'Draconia'),
cls('StudioKhimera/UberQuest', 'UberQuest'),
cls('TracesOfThePast', 'RickGriffinStudios/TracesOfThePast'),
cls('TracesOfThePast/NSFW', 'RickGriffinStudios/TracesOfThePastNSFW'),

View file

@ -210,12 +210,12 @@ class PlanescapeSurvival(_BasicScraper):
help = 'Index format: nnn'
class PlushAndBlood(_ParserScraper):
class PlushAndBlood(ParserScraper):
url = 'http://www.plushandblood.com/Comic.php'
stripUrl = url + '?strip_id=%s'
firstStripUrl = stripUrl % '1'
imageSearch = '//img[contains(@src, "comics/")]'
prevSearch = '//a[./img[contains(@src, "Nav/Prev")]]'
prevSearch = '//a[contains(text(), "PREV")]'
class PokeyThePenguin(_ParserScraper):
@ -334,8 +334,10 @@ class PS238(_ParserScraper):
class PvPOnline(ParserScraper):
baseUrl = 'https://www.toonhoundstudios.com/'
url = baseUrl + 'pvp/'
stripUrl = baseUrl + 'comic/%s/?sid=372'
stripUrl = baseUrl + 'comic/%s/'
firstStripUrl = stripUrl % '19980504'
imageSearch = '//div[@id="spliced-comic"]//img/@data-src-img'
prevSearch = '//div[d:class("comic-nav")]//a[d:class("prev")]'
help = 'Older pages need a Patreon subscription'
prevSearch = '//a[d:class("prev")]'
def namer(self, imageUrl, pageUrl):
return 'pvp' + imageUrl.rsplit('/', 1)[-1]

View file

@ -30,10 +30,11 @@ class ProjectFuture(ParserScraper):
cls('BookOfTenets', 'tenets', '01', last='45'),
cls('CriticalMass', 'criticalmass', 'cover', last='26'),
cls('DarkLordRising', 'darklord', '01-00', last='10-10'),
cls('Emily', 'emily', '01-00'),
cls('FishingTrip', 'fishing', '01-00'),
cls('Emily', 'emily', '01-00', last='07-10'),
cls('FishingTrip', 'fishing', '01-00', last='03-12'),
cls('HeadsYouLose', 'heads', '00-01', last='07-12'),
cls('IPanther', 'panther', '00'),
cls('InnocenceGuiltAndChange', 'ernst', '01-00'),
cls('IPanther', 'panther', '00', last='20'),
cls('NiallsStory', 'niall', '00'),
cls('ProjectFuture', 'strip', '0', last='664'),
cls('RedValentine', 'redvalentine', '1', last='6'),
@ -42,10 +43,12 @@ class ProjectFuture(ParserScraper):
cls('TheAxemanCometh', 'axeman', '01-01', last='02-18'),
cls('ToCatchADemon', 'daxxon', '01-00', last='03-14'),
cls('TheDarkAngel', 'darkangel', 'cover', last='54'),
cls('TheBountyProject', 'bounty', '00-00'),
cls('TheEpsilonProject', 'epsilon', '00-01'),
cls('TheHarvest', 'harvest', '01-00'),
cls('TheHarvest', 'harvest', '01-00', last='08-26'),
cls('TheSierraChronicles', 'sierra', '0', last='29'),
cls('TheTuppenyMan', 'tuppenny', '00', last='16'),
cls('TurningANewPage', 'azrael', '1', last='54'),
cls('Xerian', 'xerian', '01-00'),
cls('ZetaTakesATrip', 'zeta', '0-00'),
)

View file

@ -7,11 +7,19 @@ from re import compile
from urllib.parse import urljoin
from ..helpers import bounceStarter
from ..scraper import _BasicScraper, _ParserScraper
from ..scraper import ParserScraper, _BasicScraper, _ParserScraper
from ..util import tagre
from .common import WordPressScraper, WordPressNavi, WordPressWebcomic
class Rainburn(ParserScraper):
url = 'https://rainburn.virmir.com/'
stripUrl = url + 'comic.php?page=%s'
firstStripUrl = stripUrl % '1'
imageSearch = '//div[@class="comic"]//img'
prevSearch = '//a[contains(@class, "prev")]'
class RalfTheDestroyer(WordPressScraper):
url = 'http://ralfthedestroyer.com/'

View file

@ -209,10 +209,65 @@ class Sheldon(_BasicScraper):
help = 'Index format: yymmdd'
class Shifters(WordPressNavi):
url = 'http://shiftersonline.com/'
stripUrl = url + '%s/'
firstStripUrl = stripUrl % 'shifters-redux-promo'
class Shifters(ParserScraper):
baseUrl = 'https://shiftersonline.com/'
url = baseUrl + 'series/shifters-redux/'
stripUrl = baseUrl + 'comic/%s/'
firstStripUrl = stripUrl % 'chapter-1-pg-1'
imageSearch = '//div[@id="spliced-comic"]//span[@class="default-lang"]//img'
prevSearch = '//a[@class="previous-comic"]'
latestSearch = '//div[@id="comic-archive-list"]//a'
starter = indirectStarter
def namer(self, imageUrl, pageUrl):
return pageUrl.rsplit('/', 2)[1] + '.' + imageUrl.rsplit('.', 1)[-1]
class ShiftersOnGossamerWings(Shifters):
name = 'Shifters/OnGossamerWings'
baseUrl = 'https://shiftersonline.com/'
url = baseUrl + 'series/shifters-on-gossamer-wings/'
stripUrl = baseUrl + 'comic/%s/'
firstStripUrl = stripUrl % 'on-gossamer-wings-cover'
class ShiftersTheBeastWithin(Shifters):
name = 'Shifters/TheBeastWithin'
baseUrl = 'https://shiftersonline.com/'
url = baseUrl + 'series/shifters-the-beast-within/'
stripUrl = baseUrl + 'comic/%s/'
firstStripUrl = stripUrl % 'awakenings-pg-1'
endOfLife = True
def namer(self, imageUrl, pageUrl):
filename = pageUrl.rsplit('/', 2)[1] + '.' + imageUrl.rsplit('.', 1)[-1]
if filename.startswith('the-company-of-dragons'):
filename = 'in-' + filename
# Prepend chapter number to filename
chapters = [
'awakenings',
'lifting-the-veil',
'tears-of-blood',
'on-the-lam',
'shades-of-intrigue',
'catfight',
'out-of-control',
'damage-control',
'wolfs-clothing',
'strange-dreams',
'blood-bonds',
'the-other-team',
'get-ferrah',
'the-price-of-power',
'dogfight',
'surfacing',
'in-the-company-of-dragons',
'filler',
]
for chapter in chapters:
if filename.startswith(chapter):
filename = 'chapter-' + str(chapters.index(chapter) + 1) + '-' + filename
return filename
class ShipInABottle(WordPressScraper):
@ -527,30 +582,18 @@ class StarCrossdDestiny(_ParserScraper):
return directory + '-' + filename
class StarfireAgency(WordPressWebcomic):
url = 'https://poecatcomix.com/starfire-agency-static/'
stripUrl = 'https://poecatcomix.com/starfire-agency/%s/'
firstStripUrl = stripUrl % '2005-09-201'
imageSearch = '//div[contains(@class, "webcomic-media")]//img'
def starter(self):
# Build list of chapters for naming
indexPage = self.getPage(self.url)
self.chapters = indexPage.xpath('//a[./img[contains(@class, "attachment-large")]]/@href')
latestPage = self.chapters[0]
self.chapters = self.chapters[1:]
self.currentChapter = len(self.chapters)
return latestPage
class StarfireAgency(ParserScraper):
url = 'https://poecatcomix.com/starfirecomic/'
stripUrl = url + '%s/'
firstStripUrl = stripUrl % 'sfa-issue-1-cover'
imageSearch = '//img[@class="scale-with-grid wp-post-image"]'
prevSearch = '//a[d:class("fixed-nav-prev")]'
latestSearch = '//div[@class="post-title"]//a'
starter = indirectStarter
adult = True
def namer(self, imageUrl, pageUrl):
page = pageUrl.rstrip('/').rsplit('/', 1)[-1]
page = page.replace('3page00', 'cover3').replace('6429', 'cover7').replace('sfa-6-5-cover', 'cover6')
page = page.replace('sfa01', 'page01').replace('sfa03', 'page03').replace('sfa04', 'page04')
page = page.replace('sfa24', 'page24').replace('sfa07', 'page')
filename = 'sfa%d-%s.%s' % (self.currentChapter, page, imageUrl.rsplit('.', 1)[-1])
if pageUrl in self.chapters:
self.currentChapter = self.currentChapter - 1
return filename
return pageUrl.rsplit('/', 2)[1] + '.' + imageUrl.rsplit('.', 1)[-1]
class StarTrip(ComicControlScraper):

View file

@ -1,65 +0,0 @@
# SPDX-License-Identifier: MIT
# Copyright (C) 2019-2022 Tobias Gruetzmacher
# Copyright (C) 2019-2020 Daniel Ring
from ..scraper import ParserScraper
from .common import WordPressScraper
class StudioKhimera(ParserScraper):
imageSearch = '//figure[@class="gallery-item"]//img/@data-src'
prevSearch = '//a[@rel="prev"]'
def __init__(self, name, sub, last=None, adult=False, fixNames=False):
super().__init__('StudioKhimera/' + name)
self.baseUrl = 'https://%s.studiokhimera.com/' % sub
self.stripUrl = self.baseUrl + '%s/'
self.url = self.baseUrl + 'category/comicChapter/?latest'
self.multipleImagesPerStrip = True
if last:
self.last = True
self.url = self.stripUrl % last
self.endOfLife = True
if adult:
self.adult = True
def starter(self):
# Retrieve list of chapter links
chapterPage = self.getPage(self.baseUrl + 'archive/')
self.chapters = chapterPage.xpath('//main//a/@href')
self.firstStripUrl = self.chapters[0]
return self.chapters[-1]
def getPrevUrl(self, url, data):
# Select previous chapter from list
index = [i for i, ch in enumerate(self.chapters) if ch == url][0]
if index == 0:
return None
return self.chapters[index - 1]
@classmethod
def getmodules(cls):
return (
cls('Mousechievous', 'mousechievous'),
)
class UberQuest(WordPressScraper):
name = 'StudioKhimera/UberQuest'
stripUrl = 'https://uberquest.studiokhimera.com/comic/page/%s/'
url = stripUrl % 'latest'
firstStripUrl = stripUrl % 'cover'
imageSearch = '//div[@class="prj--comic-image"]/img'
prevSearch = '//uq-image-button[d:class("prj--comic-control-prev")]'
def namer(self, imageUrl, pageUrl):
# Fix inconsistent filenames
filename = imageUrl.rsplit('/', 1)[-1]
filename = filename.replace('Page', 'UberQuest')
filename = filename.replace('UberQuest01.', 'UberQuest001.')
filename = filename.replace('UberQuest98.', 'UberQuest098.')
filename = filename.replace('UberQuest99.', 'UberQuest099.')
return filename

View file

@ -16,14 +16,6 @@ from .common import (ComicControlScraper, WordPressScraper, WordPressSpliced,
WordPressNavi, WordPressWebcomic)
class TailsAndTactics(_ParserScraper):
url = 'http://tailsandtactics.com/comic/'
stripUrl = url + '%s/'
firstStripUrl = stripUrl % '1'
imageSearch = '//div[@class="comic-image"]/img'
prevSearch = '//a[text()=" Back"]'
class TekMage(WordPressNavi):
url = 'https://tekmagecomic.com/'
stripUrl = url + 'comic/%s/'

View file

@ -66,6 +66,7 @@ class Tapas(ParserScraper):
cls('AmpleTime', 'Ample-Time'),
cls('FANGS', 'fangscomic'),
cls('FishNuggets', 'Fish-Nuggets'),
cls('Ginpu', 'Ginpu-Studios-Comics'),
cls('HoneyAndTheMoon', 'Honey-and-the-Moon'),
cls('InsignificantOtters', 'IOtters'),
cls('MagicalBoy', 'magicalboy'),

View file

@ -3,6 +3,7 @@
# Copyright (C) 2012-2014 Bastian Kleineidam
# Copyright (C) 2015-2020 Tobias Gruetzmacher
# Copyright (C) 2019-2020 Daniel Ring
import json
from re import compile
from urllib.parse import urljoin
from lxml import etree
@ -13,6 +14,28 @@ from ..util import tagre
from .common import ComicControlScraper, WordPressScraper, WordPressNavi
class UberQuest(ParserScraper):
baseUrl = 'https://uberquest.studiokhimera.com/'
url = baseUrl + 'wp-json/keeros_comics/v1/chapters'
stripUrl = baseUrl + 'wp-json/wp/v2/cfx_comic_page?page_number=%s'
firstStripUrl = stripUrl % 'cover'
def starter(self):
# Retrieve comic metadata from API
data = self.session.get(self.url)
data.raise_for_status()
return self.stripUrl % data.json()[-1]['pages'][-1]['page_number']
def getPrevUrl(self, url, data):
return self.stripUrl % json.loads(data.text_content())[0]['prev_id']
def fetchUrls(self, url, data, urlSearch):
return [json.loads(data.text_content())[0]['attachment']]
def namer(self, imageUrl, pageUrl):
return 'UberQuest-' + pageUrl.rsplit('=', 1)[-1]
class Underling(WordPressNavi):
url = ('https://web.archive.org/web/20190806120425/'
'http://underlingcomic.com/')

View file

@ -3,28 +3,10 @@
# Copyright (C) 2012-2014 Bastian Kleineidam
# Copyright (C) 2015-2020 Tobias Gruetzmacher
# Copyright (C) 2019-2020 Daniel Ring
from ..scraper import _ParserScraper
from ..scraper import ParserScraper, _ParserScraper
from ..helpers import bounceStarter, indirectStarter
class VampireHunterBoyfriends(_ParserScraper):
baseUrl = 'https://boneitisindustries.com/'
url = baseUrl + 'comics/vampire-hunter-boyfriends/'
stripUrl = baseUrl + 'comic/%s/'
firstStripUrl = stripUrl % 'vampire-hunter-boyfriends-chapter-1-cover'
imageSearch = '//div[@id="content"]//img[d:class("size-full")]'
prevSearch = '//a[./span[d:class("ticon-chevron-left")]]'
adult = True
def starter(self):
archivePage = self.getPage(self.url)
self.archive = archivePage.xpath('//div[contains(@class, "vcex-portfolio-grid")]//a/@href')
return self.archive[-1]
def getPrevUrl(self, url, data):
return self.archive[self.archive.index(url) - 1]
class Vexxarr(_ParserScraper):
baseUrl = 'http://www.vexxarr.com/'
url = baseUrl + 'Index.php'
@ -82,3 +64,11 @@ class VirmirWorld(_ParserScraper):
def getIndexStripUrl(self, index):
index = index.split('-')
return self.stripUrl % (index[0], index[1])
class Vreakerz(ParserScraper):
url = 'http://vreakerz.angrykitten.nl/'
stripUrl = url + 'stories/read/%s'
firstStripUrl = stripUrl % '1'
imageSearch = '//img[contains(@src, "storypages")]'
prevSearch = '//a[@class="btn-prior"]'

View file

@ -5,7 +5,7 @@
# Copyright (C) 2019-2020 Daniel Ring
from re import compile, escape, IGNORECASE
from ..scraper import _BasicScraper, _ParserScraper
from ..scraper import ParserScraper, _BasicScraper, _ParserScraper
from ..util import tagre
from ..helpers import bounceStarter
from .common import ComicControlScraper, WordPressScraper, WordPressNaviIn, WordPressWebcomic
@ -36,13 +36,12 @@ class WebcomicName(_ParserScraper):
multipleImagesPerStrip = True
class Weregeek(_ParserScraper):
class Weregeek(ParserScraper):
url = 'http://www.weregeek.com/'
stripUrl = url + '%s/'
firstStripUrl = stripUrl % '2006/11/27'
imageSearch = '//div[@id="comic"]/img'
prevSearch = '//a[./img[@alt="Previous"]]'
help = 'Index format: yyyy/mm/dd'
stripUrl = url + 'comic/%s/'
firstStripUrl = stripUrl % 'comic-1'
imageSearch = '//div[d:class("webcomic-media")]//img'
prevSearch = '//a[d:class("previous-webcomic-link")]'
class WereIWolf(_ParserScraper):

View file

@ -87,6 +87,7 @@ class WebToons(ParserScraper):
cls('BehindTheGIFs', 'comedy/behind-the-gifs', 658),
cls('BigJo', 'romance/big-jo', 854),
cls('BiteMe', 'thriller/bite-me', 1019),
cls('BitterSweetCoffee', 'challenge/bitter-sweet-coffee', 797203),
cls('Blackened', 'challenge/blackened', 363805),
cls('BladesOfFurry', 'romance/blades-of-furry', 2383),
cls('Blessed', 'drama/blessed', 1193),
@ -105,6 +106,7 @@ class WebToons(ParserScraper):
cls('CARL', 'slice-of-life/carl', 1216),
cls('Caster', 'action/caster', 1461),
cls('CastleSwimmer', 'fantasy/castle-swimmer', 1499),
cls('CatchMeIfYouCan', 'challenge/catch-me-if-you-can-', 434808),
cls('Catharsis', 'fantasy/catharsis', 396),
cls('CatLoafAdventures', 'slice-of-life/cat-loaf-adventures', 1381),
cls('CChansACatgirl', 'challenge/c-chans-a-catgirl', 263430),
@ -120,7 +122,7 @@ class WebToons(ParserScraper):
cls('CodeAdam', 'action/code-adam', 1657),
cls('CookingComically', 'tiptoon/cooking-comically', 622),
cls('Crumbs', 'romance/crumbs', 1648),
cls('CrystalVirus', 'challenge/crystal-virus', 347038),
cls('CrystalVirusOtherStory', 'challenge/crystal-virus-other-story', 837028),
cls('CupidsArrows', 'romance/cupids-arrows', 1538),
cls('CursedPrincessClub', 'comedy/cursed-princess-club', 1537),
cls('Cyberbunk', 'sf/cyberbunk', 466),
@ -273,6 +275,7 @@ class WebToons(ParserScraper):
cls('MidnightRain', 'drama/midnight-rain', 1797),
cls('MidnightRhapsody', 'slice-of-life/midnight-rhapsody', 116),
cls('MidnightRhapsodySeason2', 'slice-of-life/midnight-rhapsody-season2', 365),
cls('Miez', 'sf/miez', 2719),
cls('MissAbbottAndTheDoctor', 'romance/miss-abbott-and-the-doctor', 707),
cls('MonsterIsle', 'challenge/monster-isle', 531999),
cls('MOONBEARD', 'comedy/moon-beard', 471),
@ -301,12 +304,12 @@ class WebToons(ParserScraper):
cls('NoScope', 'sports/no-scope', 1572),
cls('NotEvenBones', 'thriller/not-even-bones', 1756),
cls('NothingSpecial', 'fantasy/nothing-special', 1188),
cls('NotSoLucky', 'challenge/not-so-lucky', 673387),
cls('OddGirlOut', 'drama/odd-girl-out', 1420),
cls('OhHoly', 'romance/oh-holy', 809),
cls('OmniscientReader', 'action/omniscient-reader', 2154),
cls('ORANGEMARMALADE', 'romance/orange-marmalade', 97),
cls('Outrage', 'super-hero/outrage', 1450),
cls('OVERPOWERED', 'challenge/overpowered', 85292),
cls('PacificRimAmara', 'sf/pacific-rim-amara', 1327),
cls('PandorasBlogs', 'challenge/pandoras-blogs', 532007),
cls('PaperRoses', 'challenge/paper-roses', 39736),
@ -401,6 +404,7 @@ class WebToons(ParserScraper):
cls('TheRoomies', 'challenge/the-roomies-archive', 513669),
cls('TheShadowProphet', 'drama/the-shadow-prophet', 1881),
cls('TheSoundOfYourHeart', 'comedy/the-sound-of-your-heart', 269),
cls('TheSpectrumOfUs', 'challenge/the-spectrum-of-us', 334525),
cls('TheSteamDragonExpress', 'fantasy/steam-dragon-express', 1270),
cls('TheStoriesOfThoseAroundMe', 'romance/the-stories-of-those-around-me', 96),
cls('TheStrangeTalesOfOscarZahn', 'fantasy/the-strange-tales-of-oscar-zahn', 685),
@ -453,6 +457,7 @@ class WebToons(ParserScraper):
cls('WitchCreekRoad', 'horror/witch-creek-road', 1453),
cls('WitchHunt', 'supernatural/witch-hunt', 363),
cls('Wolfsbane', 'horror/wolfsbane', 1826),
cls('WorldsStrongestTroll', 'fantasy/worlds-strongest-troll', 5315),
cls('XINK3R', 'super-hero/xinker', 541),
cls('YourAdventure', 'comedy/your-adventure', 506),
cls('YourLetter', 'drama/your-letter', 1540),