238 lines
9.5 KiB
Python
238 lines
9.5 KiB
Python
"""Platform information API endpoints.
|
|
|
|
Provides information about supported platforms and their configuration options.
|
|
"""
|
|
|
|
from quart import Blueprint, jsonify
|
|
|
|
from app.services.gallery_dl import GalleryDLService
|
|
|
|
bp = Blueprint("platforms", __name__)
|
|
|
|
|
|
@bp.route("", methods=["GET"])
|
|
async def list_platforms():
|
|
"""List all supported platforms with their configuration options."""
|
|
gdl_service = GalleryDLService()
|
|
|
|
platforms = {
|
|
"patreon": {
|
|
"name": "Patreon",
|
|
"description": "Download posts from Patreon creators",
|
|
"requires_auth": True,
|
|
"auth_type": "cookies",
|
|
"url_pattern": "https://www.patreon.com/{creator}",
|
|
"url_examples": [
|
|
"https://www.patreon.com/example_artist",
|
|
"https://www.patreon.com/user?u=12345678",
|
|
],
|
|
"content_types": gdl_service.get_platform_content_types("patreon"),
|
|
"content_type_descriptions": {
|
|
"images": "Standard post images",
|
|
"image_large": "High-resolution image versions",
|
|
"attachments": "File attachments (ZIP, PSD, etc.)",
|
|
"postfile": "Post-specific files",
|
|
"content": "Embedded content in post body",
|
|
},
|
|
"default_config": gdl_service.get_default_config_for_platform("patreon"),
|
|
},
|
|
"subscribestar": {
|
|
"name": "SubscribeStar",
|
|
"description": "Download posts from SubscribeStar creators",
|
|
"requires_auth": True,
|
|
"auth_type": "cookies",
|
|
"url_pattern": "https://subscribestar.{domain}/{creator}",
|
|
"url_examples": [
|
|
"https://subscribestar.adult/example_artist",
|
|
"https://www.subscribestar.com/example_artist",
|
|
],
|
|
"content_types": gdl_service.get_platform_content_types("subscribestar"),
|
|
"content_type_descriptions": {
|
|
"all": "All available content",
|
|
},
|
|
"default_config": gdl_service.get_default_config_for_platform("subscribestar"),
|
|
},
|
|
"hentaifoundry": {
|
|
"name": "Hentai Foundry",
|
|
"description": "Download artwork from Hentai Foundry artists",
|
|
"requires_auth": False,
|
|
"auth_type": "cookies", # Optional but improves access
|
|
"url_pattern": "https://www.hentai-foundry.com/user/{artist}",
|
|
"url_examples": [
|
|
"https://www.hentai-foundry.com/user/example_artist",
|
|
"https://www.hentai-foundry.com/pictures/user/example_artist",
|
|
],
|
|
"content_types": gdl_service.get_platform_content_types("hentaifoundry"),
|
|
"content_type_descriptions": {
|
|
"pictures": "Artwork/pictures",
|
|
"stories": "Written stories",
|
|
},
|
|
"default_config": gdl_service.get_default_config_for_platform("hentaifoundry"),
|
|
},
|
|
"discord": {
|
|
"name": "Discord",
|
|
"description": "Download attachments from Discord channels",
|
|
"requires_auth": True,
|
|
"auth_type": "token",
|
|
"url_pattern": "https://discord.com/channels/{server}/{channel}",
|
|
"url_examples": [
|
|
"https://discord.com/channels/123456789/987654321",
|
|
],
|
|
"content_types": gdl_service.get_platform_content_types("discord"),
|
|
"content_type_descriptions": {
|
|
"all": "All attachments and embeds",
|
|
},
|
|
"default_config": gdl_service.get_default_config_for_platform("discord"),
|
|
"notes": "Requires Discord user token (not bot token)",
|
|
},
|
|
"pixiv": {
|
|
"name": "Pixiv",
|
|
"description": "Download artwork from Pixiv artists",
|
|
"requires_auth": True,
|
|
"auth_type": "cookies",
|
|
"url_pattern": "https://www.pixiv.net/users/{user_id}",
|
|
"url_examples": [
|
|
"https://www.pixiv.net/users/12345678",
|
|
"https://www.pixiv.net/en/users/12345678",
|
|
],
|
|
"content_types": gdl_service.get_platform_content_types("pixiv"),
|
|
"content_type_descriptions": {
|
|
"all": "All artwork (illustrations and manga)",
|
|
"illusts": "Illustrations only",
|
|
"manga": "Manga only",
|
|
"bookmarks": "Bookmarked works",
|
|
},
|
|
"default_config": gdl_service.get_default_config_for_platform("pixiv"),
|
|
},
|
|
"deviantart": {
|
|
"name": "DeviantArt",
|
|
"description": "Download artwork from DeviantArt artists",
|
|
"requires_auth": False,
|
|
"auth_type": "cookies",
|
|
"url_pattern": "https://www.deviantart.com/{username}",
|
|
"url_examples": [
|
|
"https://www.deviantart.com/example-artist",
|
|
"https://www.deviantart.com/example-artist/gallery",
|
|
],
|
|
"content_types": gdl_service.get_platform_content_types("deviantart"),
|
|
"content_type_descriptions": {
|
|
"all": "All deviations",
|
|
"gallery": "Gallery artwork",
|
|
"scraps": "Scraps folder",
|
|
"favorites": "Favorited works",
|
|
},
|
|
"default_config": gdl_service.get_default_config_for_platform("deviantart"),
|
|
},
|
|
}
|
|
|
|
return jsonify({"platforms": platforms})
|
|
|
|
|
|
@bp.route("/<platform>", methods=["GET"])
|
|
async def get_platform(platform: str):
|
|
"""Get detailed information about a specific platform."""
|
|
gdl_service = GalleryDLService()
|
|
|
|
if platform not in ["patreon", "subscribestar", "hentaifoundry", "discord", "pixiv", "deviantart"]:
|
|
return jsonify({"error": f"Unknown platform: {platform}"}), 404
|
|
|
|
# Get the full platform info from list_platforms
|
|
all_platforms = (await list_platforms()).get_json()
|
|
platform_info = all_platforms["platforms"].get(platform)
|
|
|
|
if not platform_info:
|
|
return jsonify({"error": f"Platform not found: {platform}"}), 404
|
|
|
|
return jsonify(platform_info)
|
|
|
|
|
|
@bp.route("/<platform>/config-schema", methods=["GET"])
|
|
async def get_config_schema(platform: str):
|
|
"""Get the configuration schema for a platform.
|
|
|
|
This defines what options can be set per-source for this platform.
|
|
Useful for building dynamic forms in the frontend.
|
|
"""
|
|
if platform not in ["patreon", "subscribestar", "hentaifoundry", "discord", "pixiv", "deviantart"]:
|
|
return jsonify({"error": f"Unknown platform: {platform}"}), 404
|
|
|
|
gdl_service = GalleryDLService()
|
|
content_types = gdl_service.get_platform_content_types(platform)
|
|
defaults = gdl_service.get_default_config_for_platform(platform)
|
|
|
|
schema = {
|
|
"platform": platform,
|
|
"fields": [
|
|
{
|
|
"name": "content_types",
|
|
"type": "multiselect",
|
|
"label": "Content Types to Download",
|
|
"description": "Select which types of content to download from this source",
|
|
"options": content_types,
|
|
"default": defaults.get("content_types", ["all"]),
|
|
},
|
|
{
|
|
"name": "sleep",
|
|
"type": "number",
|
|
"label": "Delay Between Downloads (seconds)",
|
|
"description": "Time to wait between downloading files. Higher values are safer but slower.",
|
|
"min": 0.5,
|
|
"max": 30.0,
|
|
"step": 0.5,
|
|
"default": defaults.get("sleep", 3.0),
|
|
},
|
|
{
|
|
"name": "sleep_request",
|
|
"type": "number",
|
|
"label": "Delay Between Requests (seconds)",
|
|
"description": "Time to wait between API requests. Helps avoid rate limiting.",
|
|
"min": 0.5,
|
|
"max": 15.0,
|
|
"step": 0.5,
|
|
"default": defaults.get("sleep_request", 1.5),
|
|
},
|
|
{
|
|
"name": "skip_existing",
|
|
"type": "boolean",
|
|
"label": "Skip Already Downloaded",
|
|
"description": "Skip files that have already been downloaded (uses archive database)",
|
|
"default": True,
|
|
},
|
|
{
|
|
"name": "save_metadata",
|
|
"type": "boolean",
|
|
"label": "Save Metadata",
|
|
"description": "Save JSON metadata file alongside each downloaded file",
|
|
"default": True,
|
|
},
|
|
{
|
|
"name": "timeout",
|
|
"type": "number",
|
|
"label": "Download Timeout (seconds)",
|
|
"description": "Maximum time to wait for a single download before giving up",
|
|
"min": 60,
|
|
"max": 7200,
|
|
"step": 60,
|
|
"default": 3600,
|
|
},
|
|
{
|
|
"name": "directory_pattern",
|
|
"type": "text",
|
|
"label": "Directory Pattern (Advanced)",
|
|
"description": "Custom directory structure pattern. Leave empty for platform default.",
|
|
"placeholder": defaults.get("directory_pattern", ""),
|
|
"default": None,
|
|
},
|
|
{
|
|
"name": "filename_pattern",
|
|
"type": "text",
|
|
"label": "Filename Pattern (Advanced)",
|
|
"description": "Custom filename pattern. Leave empty for platform default.",
|
|
"placeholder": defaults.get("filename_pattern", ""),
|
|
"default": None,
|
|
},
|
|
],
|
|
}
|
|
|
|
return jsonify(schema)
|