2012-12-12 16:41:29 +00:00
|
|
|
#!/usr/bin/env python
|
2016-04-12 22:52:16 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2016-10-28 22:21:41 +00:00
|
|
|
# Copyright (C) 2004-2008 Tristan Seligmann and Jonathan Jacobs
|
2014-01-05 15:50:57 +00:00
|
|
|
# Copyright (C) 2012-2014 Bastian Kleineidam
|
2017-02-12 21:36:06 +00:00
|
|
|
# Copyright (C) 2015-2017 Tobias Gruetzmacher
|
2012-12-12 16:41:29 +00:00
|
|
|
"""
|
2016-04-12 22:52:16 +00:00
|
|
|
Script to get a list of smackjeeves.com comics and save the info in a JSON file
|
|
|
|
for further processing.
|
2012-12-12 16:41:29 +00:00
|
|
|
"""
|
2016-04-12 22:52:16 +00:00
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
|
2012-12-12 16:41:29 +00:00
|
|
|
import sys
|
2016-05-05 21:33:48 +00:00
|
|
|
from six.moves.urllib.parse import urlsplit
|
2016-04-20 21:48:29 +00:00
|
|
|
|
|
|
|
from scriptutil import ComicListUpdater
|
|
|
|
|
|
|
|
|
|
|
|
class SmackJeevesUpdater(ComicListUpdater):
|
|
|
|
# Absolute minumum number of pages a comic may have (restrict search space)
|
|
|
|
MIN_COMICS = 90
|
|
|
|
|
|
|
|
# names of comics to exclude
|
|
|
|
excluded_comics = (
|
|
|
|
# comic moved/we have a better module
|
|
|
|
"Amya",
|
|
|
|
"Footloose",
|
|
|
|
"TitleUnrelated",
|
|
|
|
|
|
|
|
# does not follow standard layout
|
|
|
|
"300DaysOfSyao",
|
|
|
|
"ADifferentPerspective",
|
|
|
|
"Captor",
|
|
|
|
"ClubLove",
|
|
|
|
"Comatose",
|
|
|
|
"DeSTRESS",
|
|
|
|
"DreamCatcher",
|
|
|
|
"Fumiko",
|
|
|
|
"GART",
|
|
|
|
"GarytheAlchemist",
|
|
|
|
"ItoshiisCrazyNuzlockeAdventures",
|
|
|
|
"JennyHaniver",
|
|
|
|
"KiLAiLO",
|
|
|
|
"LoudEra",
|
|
|
|
"LunarHill",
|
|
|
|
"Mafiagame",
|
|
|
|
"MylifewithFel",
|
|
|
|
"MyLifewithFelENESPANOL",
|
|
|
|
"NegativeZen",
|
|
|
|
"Nemutionpobae",
|
|
|
|
"NightShot",
|
|
|
|
"NormalIsBoring",
|
|
|
|
"OpticalDisarray",
|
|
|
|
"PicturesofYou",
|
|
|
|
"Pornjunkiesstrip",
|
|
|
|
"PrettyUgly",
|
|
|
|
"Project217",
|
|
|
|
"RemmyzRandomz",
|
|
|
|
"Ribon",
|
|
|
|
"RubysWorld",
|
|
|
|
"ShinkaTheLastEevee",
|
|
|
|
"SimplePixel",
|
|
|
|
"SladesMansionofawesomeness",
|
|
|
|
"SpaceSchool",
|
|
|
|
"SushiGummy",
|
|
|
|
"TC2KsPokemobians",
|
|
|
|
"TheAfterSubtract",
|
|
|
|
"ThePokemonArtBox",
|
|
|
|
"THEVOIDWEBCOMIC",
|
|
|
|
"ToDefeatThemAll",
|
|
|
|
"TwoKeys",
|
|
|
|
"Vbcomics",
|
|
|
|
"WerewolfRichard",
|
|
|
|
|
|
|
|
# has no previous comic link
|
|
|
|
"ThreadCrashers",
|
|
|
|
"AchievementStuck",
|
|
|
|
|
|
|
|
# images are 403 forbidden
|
|
|
|
"AngelJunkPileFelix",
|
|
|
|
"AntavioussGenLab",
|
2016-04-21 23:04:47 +00:00
|
|
|
"Harfang",
|
2016-04-20 21:48:29 +00:00
|
|
|
"Okamirai",
|
|
|
|
|
|
|
|
# missing images
|
2017-02-13 00:46:49 +00:00
|
|
|
"AGirlAndHerShadow",
|
|
|
|
"Carciphona",
|
2016-04-20 21:48:29 +00:00
|
|
|
"CatboyattheCon",
|
|
|
|
"ContraandtheSpamDump",
|
|
|
|
"Darkkyosshorts",
|
|
|
|
"DollarStoreCaviar",
|
|
|
|
"EdgeofDecember",
|
2017-02-13 00:46:49 +00:00
|
|
|
"EvD",
|
2016-04-20 21:48:29 +00:00
|
|
|
"HAndJ",
|
|
|
|
"HEARD",
|
|
|
|
"IwillbenapoSpamDump",
|
|
|
|
"KirbysoftheAlternateDimension",
|
|
|
|
"Letsreviewshallwe",
|
|
|
|
"MegaManSpriteExpo",
|
|
|
|
"OmnisSpriteShowcase",
|
|
|
|
"PiecesofBrokenGlass",
|
|
|
|
"PlatonicManagementDilemma",
|
|
|
|
"SecretSanta2011",
|
|
|
|
"SerendipityAnEquestrianTale",
|
|
|
|
"SJArtCollab",
|
|
|
|
"SlightlyDifferent",
|
|
|
|
"TheAttackoftheRecoloursSeason1",
|
2017-02-13 00:46:49 +00:00
|
|
|
"ThroughTheWonkyEye",
|
2016-04-20 21:48:29 +00:00
|
|
|
"TotallyKotor",
|
|
|
|
"WinterMelody",
|
|
|
|
"ZonowTheHedgehog",
|
|
|
|
|
|
|
|
# missing previous link
|
|
|
|
"BambooArmonicKnightsGuild",
|
|
|
|
|
|
|
|
# broken host name
|
|
|
|
"Razor",
|
|
|
|
)
|
|
|
|
|
2017-02-12 21:36:06 +00:00
|
|
|
def __init__(self, name):
|
|
|
|
super(SmackJeevesUpdater, self).__init__(name)
|
2017-02-13 00:46:49 +00:00
|
|
|
self.sleep = 1.5
|
2017-02-12 21:36:06 +00:00
|
|
|
|
2016-04-20 21:48:29 +00:00
|
|
|
def handle_url(self, url):
|
|
|
|
"""Parse one search result page."""
|
|
|
|
data = self.get_url(url)
|
|
|
|
|
|
|
|
num = 999
|
2017-02-13 00:46:49 +00:00
|
|
|
for comictag in data.cssselect('a.card'):
|
|
|
|
page_url = comictag.attrib['href']
|
|
|
|
name = comictag.cssselect('div.title')[0].text
|
2016-04-20 21:48:29 +00:00
|
|
|
# search for url in extra page
|
|
|
|
data2 = self.get_url(page_url)
|
2017-02-13 00:46:49 +00:00
|
|
|
|
|
|
|
# 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')
|
2016-04-20 21:48:29 +00:00
|
|
|
comic_url = mo[0].attrib['href']
|
|
|
|
# search for adult flag
|
2017-02-13 00:46:49 +00:00
|
|
|
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)
|
2016-04-20 21:48:29 +00:00
|
|
|
|
2017-02-13 00:46:49 +00:00
|
|
|
next_url = data.cssselect("a.next")[0].attrib['href']
|
2016-04-20 21:48:29 +00:00
|
|
|
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.
|
2017-02-13 00:46:49 +00:00
|
|
|
next_url = "http://www.smackjeeves.com/search.php?last_update=6&sort_by=5"
|
2016-04-20 21:48:29 +00:00
|
|
|
last_count = 999
|
|
|
|
while last_count >= self.MIN_COMICS:
|
2017-02-13 00:46:49 +00:00
|
|
|
print(last_count, file=sys.stderr)
|
2016-04-20 21:48:29 +00:00
|
|
|
next_url, last_count = self.handle_url(next_url)
|
|
|
|
|
2016-05-22 20:55:06 +00:00
|
|
|
def get_entry(self, name, data):
|
2016-04-20 21:48:29 +00:00
|
|
|
sub, top = urlsplit(data[0]).hostname.split('.', 1)
|
|
|
|
if top.lower() == "smackjeeves.com":
|
2016-05-22 21:54:21 +00:00
|
|
|
opt = "sub='%s'" % sub
|
2016-04-20 21:48:29 +00:00
|
|
|
else:
|
2016-05-22 21:54:21 +00:00
|
|
|
opt = "host='%s.%s'" % (sub, top)
|
2016-04-20 21:48:29 +00:00
|
|
|
if data[1]:
|
2016-05-22 21:54:21 +00:00
|
|
|
opt += ", adult=True"
|
2017-02-13 00:46:49 +00:00
|
|
|
if data[2] == 'Completed':
|
|
|
|
opt += ", endOfLife=True"
|
2016-05-22 21:54:21 +00:00
|
|
|
return u"cls('%s', %s)," % (name, opt)
|
2012-12-12 16:41:29 +00:00
|
|
|
|
2017-05-14 22:54:02 +00:00
|
|
|
|
2012-12-12 16:41:29 +00:00
|
|
|
if __name__ == '__main__':
|
2016-04-20 21:48:29 +00:00
|
|
|
SmackJeevesUpdater(__file__).run()
|