Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
mikf
GitHub Repository: mikf/gallery-dl
Path: blob/master/gallery_dl/extractor/chevereto.py
5399 views
1
# -*- coding: utf-8 -*-
2
3
# Copyright 2023-2025 Mike Fährmann
4
#
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License version 2 as
7
# published by the Free Software Foundation.
8
9
"""Extractors for Chevereto galleries"""
10
11
from .common import BaseExtractor, Message
12
from .. import text, util
13
14
15
class CheveretoExtractor(BaseExtractor):
16
"""Base class for chevereto extractors"""
17
basecategory = "chevereto"
18
directory_fmt = ("{category}", "{user}", "{album}")
19
archive_fmt = "{id}"
20
21
def _init(self):
22
self.path = self.groups[-1]
23
24
def _pagination(self, url):
25
while True:
26
page = self.request(url).text
27
28
for item in text.extract_iter(
29
page, '<div class="list-item-image ', 'image-container'):
30
yield text.urljoin(self.root, text.extr(
31
item, '<a href="', '"'))
32
33
url = text.extr(page, 'data-pagination="next" href="', '"')
34
if not url:
35
return
36
if url[0] == "/":
37
url = self.root + url
38
39
40
BASE_PATTERN = CheveretoExtractor.update({
41
"jpgfish": {
42
"root": "https://jpg6.su",
43
"pattern": r"jpe?g\d?\.(?:su|pet|fish(?:ing)?|church)",
44
},
45
"imgkiwi": {
46
"root": "https://img.kiwi",
47
"pattern": r"img\.kiwi",
48
},
49
"imagepond": {
50
"root": "https://imagepond.net",
51
"pattern": r"imagepond\.net",
52
},
53
})
54
55
56
class CheveretoImageExtractor(CheveretoExtractor):
57
"""Extractor for chevereto images"""
58
subcategory = "image"
59
pattern = BASE_PATTERN + r"(/im(?:g|age)/[^/?#]+)"
60
example = "https://jpg2.su/img/TITLE.ID"
61
62
def items(self):
63
url = self.root + self.path
64
page = self.request(url).text
65
extr = text.extract_from(page)
66
67
url = (extr('<meta property="og:image" content="', '"') or
68
extr('url: "', '"'))
69
if not url or url.endswith("/loading.svg"):
70
pos = page.find(" download=")
71
url = text.rextr(page, 'href="', '"', pos)
72
if not url.startswith("https://"):
73
url = util.decrypt_xor(
74
url, b"seltilovessimpcity@simpcityhatesscrapers",
75
fromhex=True)
76
77
file = {
78
"id" : self.path.rpartition(".")[2],
79
"url" : url,
80
"album": text.remove_html(extr(
81
"Added to <a", "</a>").rpartition(">")[2]),
82
"date" : text.parse_datetime(extr(
83
'<span title="', '"'), "%Y-%m-%d %H:%M:%S"),
84
"user" : extr('username: "', '"'),
85
}
86
87
text.nameext_from_url(file["url"], file)
88
yield Message.Directory, file
89
yield Message.Url, file["url"], file
90
91
92
class CheveretoVideoExtractor(CheveretoExtractor):
93
"""Extractor for chevereto videos"""
94
subcategory = "video"
95
pattern = BASE_PATTERN + r"(/video/[^/?#]+)"
96
example = "https://imagepond.net/video/TITLE.ID"
97
98
def items(self):
99
url = self.root + self.path
100
page = self.request(url).text
101
extr = text.extract_from(page)
102
103
file = {
104
"id" : self.path.rpartition(".")[2],
105
"title" : text.unescape(extr(
106
'property="og:title" content="', '"')),
107
"thumbnail": extr(
108
'property="og:image" content="', '"'),
109
"url" : extr(
110
'property="og:video" content="', '"'),
111
"width" : text.parse_int(extr(
112
'property="video:width" content="', '"')),
113
"height" : text.parse_int(extr(
114
'property="video:height" content="', '"')),
115
"duration" : extr(
116
'class="far fa-clock"></i>', "—"),
117
"album": text.remove_html(extr(
118
"Added to <a", "</a>").rpartition(">")[2]),
119
"date" : text.parse_datetime(extr(
120
'<span title="', '"'), "%Y-%m-%d %H:%M:%S"),
121
"user" : extr('username: "', '"'),
122
}
123
124
try:
125
min, _, sec = file["duration"].partition(":")
126
file["duration"] = int(min) * 60 + int(sec)
127
except Exception:
128
pass
129
130
text.nameext_from_url(file["url"], file)
131
yield Message.Directory, file
132
yield Message.Url, file["url"], file
133
134
135
class CheveretoAlbumExtractor(CheveretoExtractor):
136
"""Extractor for chevereto albums"""
137
subcategory = "album"
138
pattern = BASE_PATTERN + r"(/a(?:lbum)?/[^/?#]+(?:/sub)?)"
139
example = "https://jpg2.su/album/TITLE.ID"
140
141
def items(self):
142
url = self.root + self.path
143
data = {"_extractor": CheveretoImageExtractor}
144
145
if self.path.endswith("/sub"):
146
albums = self._pagination(url)
147
else:
148
albums = (url,)
149
150
for album in albums:
151
for image in self._pagination(album):
152
yield Message.Queue, image, data
153
154
155
class CheveretoUserExtractor(CheveretoExtractor):
156
"""Extractor for chevereto users"""
157
subcategory = "user"
158
pattern = BASE_PATTERN + r"(/[^/?#]+(?:/albums)?)"
159
example = "https://jpg2.su/USER"
160
161
def items(self):
162
url = self.root + self.path
163
164
if self.path.endswith("/albums"):
165
data = {"_extractor": CheveretoAlbumExtractor}
166
for url in self._pagination(url):
167
yield Message.Queue, url, data
168
else:
169
data_image = {"_extractor": CheveretoImageExtractor}
170
data_video = {"_extractor": CheveretoVideoExtractor}
171
for url in self._pagination(url):
172
data = data_video if "/video/" in url else data_image
173
yield Message.Queue, url, data
174
175