Skip to content

Commit 1530778

Browse files
committed
merge #8917: [kaliscan] add support
2 parents e93cfa3 + 180b291 commit 1530778

File tree

5 files changed

+189
-0
lines changed

5 files changed

+189
-0
lines changed

docs/supportedsites.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,12 @@ Consider all listed sites to potentially be NSFW.
559559
<td>Favorites, Followers, Followed Users, individual Images, Playlists, Search Results, Tag Searches, User Profiles, User Images, User Playlists, User Videos, Videos</td>
560560
<td>Supported</td>
561561
</tr>
562+
<tr id="kaliscan" title="kaliscan">
563+
<td>KaliScan</td>
564+
<td>https://kaliscan.me/</td>
565+
<td>Chapters, Manga</td>
566+
<td></td>
567+
</tr>
562568
<tr id="keenspot" title="keenspot">
563569
<td>Keenspot</td>
564570
<td>http://www.keenspot.com/</td>

gallery_dl/extractor/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
"iwara",
110110
"jschan",
111111
"kabeuchi",
112+
"kaliscan",
112113
"keenspot",
113114
"kemono",
114115
"khinsider",

gallery_dl/extractor/kaliscan.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# This program is free software; you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License version 2 as
5+
# published by the Free Software Foundation.
6+
7+
"""Extractors for https://kaliscan.me/"""
8+
9+
from .common import ChapterExtractor, MangaExtractor
10+
from .. import text
11+
from ..cache import memcache
12+
13+
BASE_PATTERN = r"(?:https?://)?kaliscan\.me"
14+
15+
16+
class KaliscanBase():
17+
"""Base class for kaliscan extractors"""
18+
category = "kaliscan"
19+
root = "https://kaliscan.me"
20+
21+
@memcache(keyarg=1)
22+
def manga_data(self, manga_slug, page=None):
23+
if page is None:
24+
url = f"{self.root}/manga/{manga_slug}"
25+
page = self.request(url).text
26+
extr = text.extract_from(page)
27+
28+
manga_id = text.parse_int(extr("bookId =", ";"))
29+
title = text.unescape(extr("<h1>", "<"))
30+
if alt_titles := extr("<h2>", "<"):
31+
alt_titles = [t.strip() for t in alt_titles.split(",")]
32+
else:
33+
alt_titles = ()
34+
35+
author = text.remove_html(extr(
36+
"Authors :</strong>", "</p>"))
37+
status = text.remove_html(extr(
38+
"Status :</strong>", "</p>"))
39+
genres = [g.strip(" ,") for g in text.split_html(extr(
40+
"Genres :</strong>", "</p>"))]
41+
42+
if descr := extr('class="content"', '<div class="readmore"'):
43+
descr = text.remove_html(descr[descr.find(">")+1:]).strip()
44+
else:
45+
descr = ""
46+
47+
return {
48+
"manga" : title,
49+
"manga_id" : manga_id,
50+
"manga_slug" : manga_slug,
51+
"manga_titles": alt_titles,
52+
"author" : author,
53+
"status" : status,
54+
"genres" : genres,
55+
"description" : descr,
56+
"lang" : "en",
57+
"language" : "English",
58+
}
59+
60+
61+
class KaliscanChapterExtractor(KaliscanBase, ChapterExtractor):
62+
"""Extractor for kaliscan manga chapters"""
63+
pattern = BASE_PATTERN + r"(/manga/([\w-]+)/chapter-([\d.]+))"
64+
example = "https://kaliscan.me/manga/ID-MANGA/chapter-1"
65+
66+
def metadata(self, page):
67+
extr = text.extract_from(page)
68+
69+
manga_id = text.parse_int(extr("bookId =", ";"))
70+
extr("bookSlug =", ";")
71+
chapter_id = text.parse_int(extr("chapterId =", ";"))
72+
extr("chapterSlug =", ";")
73+
chapter_number = extr("chapterNumber =", ";").strip(' "\'')
74+
75+
chapter, sep, minor = chapter_number.partition(".")
76+
77+
data = {
78+
"chapter" : text.parse_int(chapter),
79+
"chapter_minor": sep + minor,
80+
"chapter_id" : chapter_id,
81+
**self.manga_data(self.groups[1]),
82+
}
83+
if manga_id and not data["manga_id"]:
84+
data["manga_id"] = manga_id
85+
return data
86+
87+
def images(self, page):
88+
images_str = text.extr(page, 'var chapImages = "', '"')
89+
if not images_str:
90+
return ()
91+
return [
92+
(url, None)
93+
for url in (u.strip() for u in images_str.split(","))
94+
if url
95+
]
96+
97+
98+
class KaliscanMangaExtractor(KaliscanBase, MangaExtractor):
99+
"""Extractor for kaliscan manga"""
100+
chapterclass = KaliscanChapterExtractor
101+
pattern = BASE_PATTERN + r"(/manga/([\w-]+))/?$"
102+
example = "https://kaliscan.me/manga/ID-MANGA"
103+
104+
def chapters(self, page):
105+
data = self.manga_data(self.groups[1], page)
106+
107+
chapter_list = text.extr(page, 'id="chapter-list">', '</ul>')
108+
if not chapter_list:
109+
return ()
110+
111+
results = []
112+
for li in text.extract_iter(chapter_list, "<li", "</li>"):
113+
url = text.extr(li, 'href="', '"')
114+
if not url:
115+
continue
116+
if url[0] == "/":
117+
url = self.root + url
118+
119+
chapter, sep, minor = url.rpartition(
120+
"/chapter-")[2].partition(".")
121+
122+
results.append((url, {
123+
"chapter" : text.parse_int(chapter),
124+
"chapter_minor": sep + minor,
125+
**data,
126+
}))
127+
return results

scripts/supportedsites.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
"itchio" : "itch.io",
114114
"jpgfish" : "JPG Fish",
115115
"kabeuchi" : "かべうち",
116+
"kaliscan" : "KaliScan",
116117
"mangafire" : "MangaFire",
117118
"mangareader" : "MangaReader",
118119
"mangataro" : "MangaTaro",

test/results/kaliscan.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# This program is free software; you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License version 2 as
5+
# published by the Free Software Foundation.
6+
7+
from gallery_dl.extractor import kaliscan
8+
9+
10+
__tests__ = (
11+
{
12+
"#url" : "https://kaliscan.me/manga/2142-whats-wrong-with-secretary-kim/chapter-1",
13+
"#class" : kaliscan.KaliscanChapterExtractor,
14+
"#pattern" : r"https://s\d+\.1stmggv\d*\.\w+/.+\.\w+",
15+
"#count" : 13,
16+
17+
"author" : "Jeong gyeong yun",
18+
"chapter" : 1,
19+
"chapter_minor": "",
20+
"chapter_id" : 68134,
21+
"count" : 13,
22+
"genres" : ["Comedy", "Josei", "Manhwa", "Romance", "Webtoons"],
23+
"lang" : "en",
24+
"language" : "English",
25+
"manga" : "What's Wrong with Secretary Kim?",
26+
"manga_id" : 2142,
27+
"manga_slug" : "2142-whats-wrong-with-secretary-kim",
28+
"status" : "Completed",
29+
},
30+
31+
{
32+
"#url" : "https://kaliscan.me/manga/2142-whats-wrong-with-secretary-kim/chapter-14.5",
33+
"#class" : kaliscan.KaliscanChapterExtractor,
34+
35+
"chapter" : 14,
36+
"chapter_minor": ".5",
37+
},
38+
39+
{
40+
"#url" : "https://kaliscan.me/manga/2142-whats-wrong-with-secretary-kim",
41+
"#class" : kaliscan.KaliscanMangaExtractor,
42+
"#pattern" : kaliscan.KaliscanChapterExtractor.pattern,
43+
"#count" : range(100, 200),
44+
45+
"author" : "Jeong gyeong yun",
46+
"chapter" : int,
47+
"genres" : ["Comedy", "Josei", "Manhwa", "Romance", "Webtoons"],
48+
"lang" : "en",
49+
"manga" : "What's Wrong with Secretary Kim?",
50+
"manga_id" : 2142,
51+
"status" : "Completed",
52+
},
53+
54+
)

0 commit comments

Comments
 (0)