Files
wizarr/app/forms/settings.py
Matthieu B f71e25f620 feat: add Drop media server support
Implements comprehensive Drop media server integration following the
media-server integration checklist:

## Core Implementation
- Create DropClient with RestApiMixin base class
- Implement full user management API (CRUD operations)
- Support Drop's two-step user creation (invitation → signup)
- Bearer token authentication with System tokens
- Proper error handling for missing Simple Authentication

## Integration Points
- Register client via @register_media_client decorator
- Add connection checker with API validation
- Wire into media_servers routes and forms
- Update UI templates (create/edit server modals)

## API Features
- User listing and synchronization from Drop API
- Statistics and server health monitoring
- Invitation-based user creation workflow
- Proper policy mapping (enabled, admin, displayName)

## Error Handling
- Clear messaging when Simple Authentication disabled
- Token permission validation and logging
- Graceful fallback for missing API endpoints

Drop integration ready for use once Simple Authentication
is enabled on the Drop server.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-12 12:41:45 +00:00

57 lines
2.3 KiB
Python

# app/forms/settings.py
from flask_babel import lazy_gettext as _l
from flask_wtf import FlaskForm
from wtforms import BooleanField, SelectField, StringField
from wtforms.validators import URL, DataRequired, Optional
class SettingsForm(FlaskForm):
server_type = SelectField(
str(_l("Server Type")),
choices=[
("plex", "Plex"),
("jellyfin", "Jellyfin"),
("emby", "Emby"),
("audiobookshelf", "Audiobookshelf"),
("drop", "Drop"),
("romm", "Romm"),
("komga", "Komga"),
("kavita", "Kavita"),
],
validators=[DataRequired()],
)
server_name = StringField(str(_l("Server Name")), validators=[DataRequired()])
server_url = StringField(str(_l("Server URL")), validators=[DataRequired()])
api_key = StringField(str(_l("API Key")), validators=[Optional()])
server_username = StringField(str(_l("RomM Username")), validators=[Optional()])
server_password = StringField(str(_l("RomM Password")), validators=[Optional()])
libraries = StringField(str(_l("Libraries")), validators=[Optional()])
allow_downloads = BooleanField(
str(_l("Allow Downloads")), default=False, validators=[Optional()]
)
allow_live_tv = BooleanField(
str(_l("Allow Live TV")), default=False, validators=[Optional()]
)
overseerr_url = StringField(
str(_l("Overseerr/Ombi URL")), validators=[Optional(), URL()]
)
ombi_api_key = StringField(str(_l("Ombi API Key")), validators=[Optional()])
discord_id = StringField(str(_l("Discord ID")), validators=[Optional()])
external_url = StringField(str(_l("External URL")), validators=[Optional()])
# Universal download and live TV options (no longer server-specific)
# Audiobookshelf specific
allow_downloads_audiobookshelf = BooleanField(
str(_l("Allow Downloads")), default=True, validators=[Optional()]
)
def __init__(self, install_mode: bool = False, *args, **kwargs):
super().__init__(*args, **kwargs)
if install_mode:
# During install wizard, libraries must be supplied
self.libraries.validators = [DataRequired()]
# api_key is mandatory for Plex/Jellyfin
self.api_key.validators = [DataRequired()]