aboutsummaryrefslogtreecommitdiffstats
path: root/gallery_dl/extractor/lexica.py
blob: d55d821ef3e82bf989d2ed646bd9552318e9e465 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# -*- coding: utf-8 -*-

# Copyright 2023 Mike Fährmann
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.

"""Extractors for https://lexica.art/"""

from .common import Extractor, Message
from .. import text


class LexicaSearchExtractor(Extractor):
    """Extractor for lexica.art search results"""
    category = "lexica"
    subcategory = "search"
    root = "https://lexica.art"
    directory_fmt = ("{category}", "{search_tags}")
    archive_fmt = "{id}"
    pattern = r"(?:https?://)?lexica\.art/?\?q=([^&#]+)"
    example = "https://lexica.art/?q=QUERY"

    def __init__(self, match):
        Extractor.__init__(self, match)
        self.query = match.group(1)
        self.text = text.unquote(self.query).replace("+", " ")

    def items(self):
        base = ("https://lexica-serve-encoded-images2.sharif.workers.dev"
                "/full_jpg/")
        tags = self.text

        for image in self.posts():
            image["filename"] = image["id"]
            image["extension"] = "jpg"
            image["search_tags"] = tags
            yield Message.Directory, image
            yield Message.Url, base + image["id"], image

    def posts(self):
        url = self.root + "/api/infinite-prompts"
        headers = {
            "Accept" : "application/json, text/plain, */*",
            "Referer": "{}/?q={}".format(self.root, self.query),
        }
        json = {
            "text"      : self.text,
            "searchMode": "images",
            "source"    : "search",
            "cursor"    : 0,
            "model"     : "lexica-aperture-v2",
        }

        while True:
            data = self.request(
                url, method="POST", headers=headers, json=json).json()

            prompts = {
                prompt["id"]: prompt
                for prompt in data["prompts"]
            }

            for image in data["images"]:
                image["prompt"] = prompts[image["promptid"]]
                del image["promptid"]
                yield image

            cursor = data.get("nextCursor")
            if not cursor:
                return

            json["cursor"] = cursor