5596de6ed5
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
141 lines
4.5 KiB
Python
141 lines
4.5 KiB
Python
"""FC-3b platforms registry — the single source of truth for what
|
|
FabledCurator supports.
|
|
|
|
Lifted from GallerySubscriber's
|
|
~/Nextcloud/Projects/GallerySubscriber/backend/app/api/platforms.py
|
|
and ~/.../extension/lib/platforms.js. Six platforms; auth_type and
|
|
URL patterns match GS exactly so the existing browser extension
|
|
hits FC unmodified.
|
|
"""
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Literal
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class PlatformInfo:
|
|
key: str
|
|
name: str
|
|
description: str
|
|
auth_type: Literal["cookies", "token"]
|
|
requires_auth: bool
|
|
url_pattern: str
|
|
url_examples: list[str]
|
|
default_config: dict
|
|
notes: str | None = None
|
|
|
|
|
|
# Common defaults used across most platforms; embedded per-platform
|
|
# below so per-platform overrides remain explicit.
|
|
_DEFAULTS = {
|
|
"sleep": 3.0,
|
|
"sleep_request": 1.5,
|
|
"skip_existing": True,
|
|
"save_metadata": True,
|
|
"timeout": 3600,
|
|
}
|
|
|
|
|
|
PLATFORMS: dict[str, PlatformInfo] = {
|
|
"patreon": PlatformInfo(
|
|
key="patreon",
|
|
name="Patreon",
|
|
description="Download posts from Patreon creators",
|
|
auth_type="cookies",
|
|
requires_auth=True,
|
|
url_pattern=r"^https?://(www\.)?patreon\.com/",
|
|
url_examples=[
|
|
"https://www.patreon.com/example_artist",
|
|
"https://www.patreon.com/user?u=12345678",
|
|
],
|
|
default_config={**_DEFAULTS, "content_types": ["images", "attachments"]},
|
|
),
|
|
"subscribestar": PlatformInfo(
|
|
key="subscribestar",
|
|
name="SubscribeStar",
|
|
description="Download posts from SubscribeStar creators",
|
|
auth_type="cookies",
|
|
requires_auth=True,
|
|
url_pattern=r"^https?://(www\.)?subscribestar\.(com|adult)/",
|
|
url_examples=[
|
|
"https://subscribestar.adult/example_artist",
|
|
"https://www.subscribestar.com/example_artist",
|
|
],
|
|
default_config={**_DEFAULTS, "content_types": ["all"]},
|
|
),
|
|
"hentaifoundry": PlatformInfo(
|
|
key="hentaifoundry",
|
|
name="Hentai Foundry",
|
|
description="Download artwork from Hentai Foundry artists",
|
|
auth_type="cookies",
|
|
requires_auth=False,
|
|
url_pattern=r"^https?://(www\.)?hentai-foundry\.com/",
|
|
url_examples=[
|
|
"https://www.hentai-foundry.com/user/example_artist",
|
|
"https://www.hentai-foundry.com/pictures/user/example_artist",
|
|
],
|
|
default_config={**_DEFAULTS, "content_types": ["pictures"]},
|
|
),
|
|
"discord": PlatformInfo(
|
|
key="discord",
|
|
name="Discord",
|
|
description="Download attachments from Discord channels",
|
|
auth_type="token",
|
|
requires_auth=True,
|
|
url_pattern=r"^https?://(www\.)?discord\.com/channels/",
|
|
url_examples=["https://discord.com/channels/123456789/987654321"],
|
|
default_config={**_DEFAULTS, "content_types": ["all"]},
|
|
notes="Requires Discord user token (not bot token).",
|
|
),
|
|
"pixiv": PlatformInfo(
|
|
key="pixiv",
|
|
name="Pixiv",
|
|
description="Download artwork from Pixiv artists",
|
|
auth_type="token",
|
|
requires_auth=True,
|
|
url_pattern=r"^https?://(www\.)?pixiv\.net/",
|
|
url_examples=[
|
|
"https://www.pixiv.net/users/12345678",
|
|
"https://www.pixiv.net/en/users/12345678",
|
|
],
|
|
default_config={**_DEFAULTS, "content_types": ["all"]},
|
|
notes="Requires OAuth refresh token. Run `gallery-dl oauth:pixiv` to obtain one.",
|
|
),
|
|
"deviantart": PlatformInfo(
|
|
key="deviantart",
|
|
name="DeviantArt",
|
|
description="Download artwork from DeviantArt artists",
|
|
auth_type="cookies",
|
|
requires_auth=False,
|
|
url_pattern=r"^https?://(www\.)?deviantart\.com/",
|
|
url_examples=[
|
|
"https://www.deviantart.com/example-artist",
|
|
"https://www.deviantart.com/example-artist/gallery",
|
|
],
|
|
default_config={**_DEFAULTS, "content_types": ["gallery"]},
|
|
),
|
|
}
|
|
|
|
|
|
def known_platform_keys() -> frozenset[str]:
|
|
return frozenset(PLATFORMS.keys())
|
|
|
|
|
|
def auth_type_for(platform: str) -> str | None:
|
|
info = PLATFORMS.get(platform)
|
|
return info.auth_type if info else None
|
|
|
|
|
|
def to_dict(info: PlatformInfo) -> dict:
|
|
return {
|
|
"key": info.key,
|
|
"name": info.name,
|
|
"description": info.description,
|
|
"auth_type": info.auth_type,
|
|
"requires_auth": info.requires_auth,
|
|
"url_pattern": info.url_pattern,
|
|
"url_examples": info.url_examples,
|
|
"default_config": info.default_config,
|
|
"notes": info.notes,
|
|
}
|