1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-07-19 04:49:37 +02:00

feat: add Immich server connection validation and error handling in integration settings

This commit is contained in:
Sean Morley 2025-06-05 14:28:37 -04:00
parent 6fdfb86297
commit 9d817a5ce9
13 changed files with 303 additions and 39 deletions

View file

@ -361,11 +361,76 @@ class ImmichIntegrationViewSet(viewsets.ModelViewSet):
def get_queryset(self): def get_queryset(self):
return ImmichIntegration.objects.filter(user=self.request.user) return ImmichIntegration.objects.filter(user=self.request.user)
def _validate_immich_connection(self, server_url, api_key):
"""
Validate connection to Immich server before saving integration.
Returns tuple: (is_valid, corrected_server_url, error_message)
"""
if not server_url or not api_key:
return False, server_url, "Server URL and API key are required"
# Ensure server_url has proper format
if not server_url.startswith(('http://', 'https://')):
server_url = f"https://{server_url}"
# Remove trailing slash if present
original_server_url = server_url.rstrip('/')
# Try both with and without /api prefix
test_configs = [
(original_server_url, f"{original_server_url}/users/me"),
(f"{original_server_url}/api", f"{original_server_url}/api/users/me")
]
headers = {
'X-API-Key': api_key,
'Content-Type': 'application/json'
}
for corrected_url, test_endpoint in test_configs:
try:
response = requests.get(
test_endpoint,
headers=headers,
timeout=10, # 10 second timeout
verify=True # SSL verification
)
if response.status_code == 200:
try:
json_response = response.json()
# Validate expected Immich user response structure
required_fields = ['id', 'email', 'name', 'isAdmin', 'createdAt']
if all(field in json_response for field in required_fields):
return True, corrected_url, None
else:
continue # Try next endpoint
except (ValueError, KeyError):
continue # Try next endpoint
elif response.status_code == 401:
return False, original_server_url, "Invalid API key or unauthorized access"
elif response.status_code == 403:
return False, original_server_url, "Access forbidden - check API key permissions"
# Continue to next endpoint for 404 errors
except requests.exceptions.ConnectTimeout:
return False, original_server_url, "Connection timeout - server may be unreachable"
except requests.exceptions.ConnectionError:
return False, original_server_url, "Cannot connect to server - check URL and network connectivity"
except requests.exceptions.SSLError:
return False, original_server_url, "SSL certificate error - check server certificate"
except requests.exceptions.RequestException as e:
return False, original_server_url, f"Connection failed: {str(e)}"
except Exception as e:
return False, original_server_url, f"Unexpected error: {str(e)}"
# If we get here, none of the endpoints worked
return False, original_server_url, "Immich server endpoint not found - check server URL"
def create(self, request): def create(self, request):
""" """
RESTful POST method for creating a new Immich integration. RESTful POST method for creating a new Immich integration.
""" """
# Check if the user already has an integration # Check if the user already has an integration
user_integrations = ImmichIntegration.objects.filter(user=request.user) user_integrations = ImmichIntegration.objects.filter(user=request.user)
if user_integrations.exists(): if user_integrations.exists():
@ -380,11 +445,76 @@ class ImmichIntegrationViewSet(viewsets.ModelViewSet):
serializer = self.serializer_class(data=request.data) serializer = self.serializer_class(data=request.data)
if serializer.is_valid(): if serializer.is_valid():
serializer.save(user=request.user) # Validate Immich server connection before saving
server_url = serializer.validated_data.get('server_url')
api_key = serializer.validated_data.get('api_key')
is_valid, corrected_server_url, error_message = self._validate_immich_connection(server_url, api_key)
if not is_valid:
return Response(
{
'message': f'Cannot connect to Immich server: {error_message}',
'error': True,
'code': 'immich.connection_failed',
'details': error_message
},
status=status.HTTP_400_BAD_REQUEST
)
# If validation passes, save the integration with the corrected URL
serializer.save(user=request.user, server_url=corrected_server_url)
return Response( return Response(
serializer.data, serializer.data,
status=status.HTTP_201_CREATED status=status.HTTP_201_CREATED
) )
return Response(
serializer.errors,
status=status.HTTP_400_BAD_REQUEST
)
def update(self, request, pk=None):
"""
RESTful PUT method for updating an existing Immich integration.
"""
integration = ImmichIntegration.objects.filter(user=request.user, id=pk).first()
if not integration:
return Response(
{
'message': 'Integration not found.',
'error': True,
'code': 'immich.integration_not_found'
},
status=status.HTTP_404_NOT_FOUND
)
serializer = self.serializer_class(integration, data=request.data, partial=True)
if serializer.is_valid():
# Validate Immich server connection before updating
server_url = serializer.validated_data.get('server_url', integration.server_url)
api_key = serializer.validated_data.get('api_key', integration.api_key)
is_valid, corrected_server_url, error_message = self._validate_immich_connection(server_url, api_key)
if not is_valid:
return Response(
{
'message': f'Cannot connect to Immich server: {error_message}',
'error': True,
'code': 'immich.connection_failed',
'details': error_message
},
status=status.HTTP_400_BAD_REQUEST
)
# If validation passes, save the integration with the corrected URL
serializer.save(server_url=corrected_server_url)
return Response(
serializer.data,
status=status.HTTP_200_OK
)
return Response( return Response(
serializer.errors, serializer.errors,
status=status.HTTP_400_BAD_REQUEST status=status.HTTP_400_BAD_REQUEST
@ -411,10 +541,9 @@ class ImmichIntegrationViewSet(viewsets.ModelViewSet):
}, },
status=status.HTTP_200_OK status=status.HTTP_200_OK
) )
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
# If the user has an integration, we only want to return that integration # If the user has an integration, we only want to return that integration
user_integrations = ImmichIntegration.objects.filter(user=request.user) user_integrations = ImmichIntegration.objects.filter(user=request.user)
if user_integrations.exists(): if user_integrations.exists():
integration = user_integrations.first() integration = user_integrations.first()

View file

@ -669,7 +669,15 @@
"api_key_placeholder": "Geben Sie Ihren Immich -API -Schlüssel ein", "api_key_placeholder": "Geben Sie Ihren Immich -API -Schlüssel ein",
"enable_integration": "Integration aktivieren", "enable_integration": "Integration aktivieren",
"immich_integration_desc": "Schließen Sie Ihren Immich -Photo -Management -Server an", "immich_integration_desc": "Schließen Sie Ihren Immich -Photo -Management -Server an",
"need_help": "Benötigen Sie Hilfe bei der Einrichtung? \nSchauen Sie sich das an" "need_help": "Benötigen Sie Hilfe bei der Einrichtung? \nSchauen Sie sich das an",
"connection_error": "Fehler, die eine Verbindung zum Immich -Server herstellen",
"copy_locally": "Kopieren Sie Bilder lokal",
"copy_locally_desc": "Kopieren Sie Bilder auf den Server für den Offline -Zugriff. \nNutzt mehr Speicherplatz.",
"error_saving_image": "Fehler speichern Bild",
"integration_already_exists": "Es gibt bereits eine Immichintegration. \nSie können jeweils nur eine Integration haben.",
"integration_not_found": "Immich -Integration nicht gefunden. \nBitte erstellen Sie eine neue Integration.",
"network_error": "Netzwerkfehler beim Verbindung mit dem Immich -Server. \nBitte überprüfen Sie Ihre Verbindung und versuchen Sie es erneut.",
"validation_error": "Bei der Validierung der Immichintegration trat ein Fehler auf. \nBitte überprüfen Sie Ihre Server -URL- und API -Schlüssel."
}, },
"recomendations": { "recomendations": {
"address": "Adresse", "address": "Adresse",
@ -712,5 +720,8 @@
"type": "Typ", "type": "Typ",
"villa": "Villa", "villa": "Villa",
"current_timezone": "Aktuelle Zeitzone" "current_timezone": "Aktuelle Zeitzone"
},
"google_maps": {
"google_maps_integration_desc": "Verbinden Sie Ihr Google Maps-Konto, um hochwertige Suchergebnisse und Empfehlungen für Standort zu erhalten."
} }
} }

View file

@ -702,7 +702,12 @@
"need_help": "Need help setting this up? Check out the", "need_help": "Need help setting this up? Check out the",
"copy_locally": "Copy Images Locally", "copy_locally": "Copy Images Locally",
"copy_locally_desc": "Copy images to the server for offline access. Uses more disk space.", "copy_locally_desc": "Copy images to the server for offline access. Uses more disk space.",
"error_saving_image": "Error saving image" "error_saving_image": "Error saving image",
"connection_error": "Error connecting to Immich server",
"integration_already_exists": "An Immich integration already exists. You can only have one integration at a time.",
"integration_not_found": "Immich integration not found. Please create a new integration.",
"validation_error": "An error occurred while validating the Immich integration. Please check your server URL and API key.",
"network_error": "Network error while connecting to the Immich server. Please check your connection and try again."
}, },
"google_maps": { "google_maps": {
"google_maps_integration_desc": "Connect your Google Maps account to get high-quality location search results and recommendations." "google_maps_integration_desc": "Connect your Google Maps account to get high-quality location search results and recommendations."

View file

@ -669,7 +669,15 @@
"api_key_placeholder": "Ingrese su clave de API IMICH", "api_key_placeholder": "Ingrese su clave de API IMICH",
"enable_integration": "Habilitar la integración", "enable_integration": "Habilitar la integración",
"immich_integration_desc": "Conecte su servidor de administración de fotos de Immich", "immich_integration_desc": "Conecte su servidor de administración de fotos de Immich",
"need_help": "¿Necesita ayuda para configurar esto? \nMira el" "need_help": "¿Necesita ayuda para configurar esto? \nMira el",
"connection_error": "Error conectarse al servidor Immich",
"copy_locally": "Copiar imágenes localmente",
"copy_locally_desc": "Copie imágenes al servidor para obtener acceso fuera de línea. \nUtiliza más espacio en disco.",
"error_saving_image": "Imagen de ahorro de errores",
"integration_already_exists": "Ya existe una integración IMICH. \nSolo puedes tener una integración a la vez.",
"integration_not_found": "Integración IMACH no encontrada. \nPor favor cree una nueva integración.",
"network_error": "Error de red mientras se conecta al servidor Immich. \nVerifique su conexión y vuelva a intentarlo.",
"validation_error": "Se produjo un error al validar la integración de Immich. \nVerifique la URL y la tecla API de su servidor."
}, },
"recomendations": { "recomendations": {
"address": "DIRECCIÓN", "address": "DIRECCIÓN",
@ -712,5 +720,8 @@
"villa": "Villa", "villa": "Villa",
"edit_lodging": "Editar alojamiento", "edit_lodging": "Editar alojamiento",
"current_timezone": "Zona horaria" "current_timezone": "Zona horaria"
},
"google_maps": {
"google_maps_integration_desc": "Conecte su cuenta de Google Maps para obtener resultados y recomendaciones de búsqueda de ubicación de alta calidad."
} }
} }

View file

@ -669,7 +669,15 @@
"api_key_placeholder": "Entrez votre clé API Immich", "api_key_placeholder": "Entrez votre clé API Immich",
"enable_integration": "Activer l'intégration", "enable_integration": "Activer l'intégration",
"immich_integration_desc": "Connectez votre serveur de gestion de photos Immich", "immich_integration_desc": "Connectez votre serveur de gestion de photos Immich",
"need_help": "Besoin d'aide pour la configurer? \nDécouvrez le" "need_help": "Besoin d'aide pour la configurer? \nDécouvrez le",
"connection_error": "Erreur de connexion à Immich Server",
"copy_locally": "Copier les images localement",
"copy_locally_desc": "Copiez des images sur le serveur pour un accès hors ligne. \nUtilise plus d'espace disque.",
"error_saving_image": "Image d'enregistrement d'erreur",
"integration_already_exists": "Une intégration Immich existe déjà. \nVous ne pouvez avoir qu'une seule intégration à la fois.",
"integration_not_found": "L'intégration d'immich n'est pas trouvée. \nVeuillez créer une nouvelle intégration.",
"network_error": "Erreur réseau lors de la connexion au serveur Immich. \nVeuillez vérifier votre connexion et réessayer.",
"validation_error": "Une erreur s'est produite lors de la validation de l'intégration d'Immich. \nVeuillez vérifier l'URL et la clé API de votre serveur."
}, },
"recomendations": { "recomendations": {
"address": "Adresse", "address": "Adresse",
@ -712,5 +720,8 @@
"type": "Type", "type": "Type",
"villa": "Villa", "villa": "Villa",
"current_timezone": "Fuseau horaire actuel" "current_timezone": "Fuseau horaire actuel"
},
"google_maps": {
"google_maps_integration_desc": "Connectez votre compte Google Maps pour obtenir des résultats de recherche et recommandations de recherche de haute qualité."
} }
} }

View file

@ -669,7 +669,15 @@
"api_key_placeholder": "Inserisci la tua chiave API immich", "api_key_placeholder": "Inserisci la tua chiave API immich",
"enable_integration": "Abilita l'integrazione", "enable_integration": "Abilita l'integrazione",
"immich_integration_desc": "Collega il tuo server di gestione delle foto immich", "immich_integration_desc": "Collega il tuo server di gestione delle foto immich",
"need_help": "Hai bisogno di aiuto per impostare questo? \nDai un'occhiata al" "need_help": "Hai bisogno di aiuto per impostare questo? \nDai un'occhiata al",
"connection_error": "Errore che si collega al server immich",
"copy_locally": "Copia immagini localmente",
"error_saving_image": "Errore salvare l'immagine",
"integration_already_exists": "Esiste già un'integrazione immich. \nPuoi avere solo un'integrazione alla volta.",
"integration_not_found": "Integrazione immich non trovata. \nSi prega di creare una nuova integrazione.",
"network_error": "Errore di rete durante la connessione al server immich. \nControlla la tua connessione e riprova.",
"validation_error": "Si è verificato un errore durante la convalida dell'integrazione immich. \nControlla l'URL e la chiave API del server.",
"copy_locally_desc": "Copia le immagini sul server per l'accesso offline. \nUtilizza più spazio su disco."
}, },
"recomendations": { "recomendations": {
"address": "Indirizzo", "address": "Indirizzo",
@ -712,5 +720,8 @@
"lodging_type": "Tipo di alloggio", "lodging_type": "Tipo di alloggio",
"motel": "Motel", "motel": "Motel",
"current_timezone": "Fuso orario attuale" "current_timezone": "Fuso orario attuale"
},
"google_maps": {
"google_maps_integration_desc": "Collega il tuo account Google Maps per ottenere risultati e consigli di ricerca sulla posizione di alta qualità."
} }
} }

View file

@ -387,7 +387,15 @@
"api_key_placeholder": "Immich API 키를 입력하십시오", "api_key_placeholder": "Immich API 키를 입력하십시오",
"enable_integration": "통합을 활성화합니다", "enable_integration": "통합을 활성화합니다",
"immich_integration_desc": "Immich Photo Management Server를 연결하십시오", "immich_integration_desc": "Immich Photo Management Server를 연결하십시오",
"need_help": "이것을 설정하는 데 도움이 필요하십니까? \n확인하십시오" "need_help": "이것을 설정하는 데 도움이 필요하십니까? \n확인하십시오",
"connection_error": "Immich 서버에 연결하는 오류",
"copy_locally": "로컬에서 이미지를 복사하십시오",
"copy_locally_desc": "오프라인 액세스를 위해 이미지를 서버에 복사하십시오. \n더 많은 디스크 공간을 사용합니다.",
"error_saving_image": "오류 저장 이미지",
"integration_already_exists": "면역 통합이 이미 존재합니다. \n한 번에 하나만 통합 할 수 있습니다.",
"integration_not_found": "Immich 통합을 찾을 수 없습니다. \n새로운 통합을 작성하십시오.",
"network_error": "Immich 서버에 연결하는 동안 네트워크 오류. \n연결을 확인하고 다시 시도하십시오.",
"validation_error": "면역 통합을 검증하는 동안 오류가 발생했습니다. \n서버 URL 및 API 키를 확인하십시오."
}, },
"map": { "map": {
"add_adventure": "새로운 모험 추가", "add_adventure": "새로운 모험 추가",
@ -711,5 +719,8 @@
"type": "유형", "type": "유형",
"villa": "별장", "villa": "별장",
"check_out": "체크 아웃" "check_out": "체크 아웃"
},
"google_maps": {
"google_maps_integration_desc": "Google지도 계정을 연결하여 고품질 위치 검색 결과 및 권장 사항을 얻으십시오."
} }
} }

View file

@ -669,7 +669,15 @@
"api_key_placeholder": "Voer uw Immich API -sleutel in", "api_key_placeholder": "Voer uw Immich API -sleutel in",
"enable_integration": "Integratie inschakelen", "enable_integration": "Integratie inschakelen",
"immich_integration_desc": "Verbind uw Immich Photo Management Server", "immich_integration_desc": "Verbind uw Immich Photo Management Server",
"need_help": "Hulp nodig bij het opzetten van dit? \nBekijk de" "need_help": "Hulp nodig bij het opzetten van dit? \nBekijk de",
"connection_error": "Error verbinding maken met Immich Server",
"copy_locally": "Kopieer afbeeldingen lokaal",
"copy_locally_desc": "Kopieer afbeeldingen naar de server voor offline toegang. \nGebruikt meer schijfruimte.",
"error_saving_image": "Foutopslagafbeelding",
"integration_already_exists": "Er bestaat al een Immich -integratie. \nU kunt maar één integratie tegelijk hebben.",
"integration_not_found": "Immich -integratie niet gevonden. \nMaak een nieuwe integratie.",
"network_error": "Netwerkfout terwijl u verbinding maakt met de Immich -server. \nControleer uw verbinding en probeer het opnieuw.",
"validation_error": "Er is een fout opgetreden bij het valideren van de Immich -integratie. \nControleer uw server -URL en API -toets."
}, },
"recomendations": { "recomendations": {
"address": "Adres", "address": "Adres",
@ -712,5 +720,8 @@
"type": "Type", "type": "Type",
"villa": "Villa", "villa": "Villa",
"current_timezone": "Huidige tijdzone" "current_timezone": "Huidige tijdzone"
},
"google_maps": {
"google_maps_integration_desc": "Sluit uw Google Maps-account aan om zoekresultaten en aanbevelingen van hoge kwaliteit te krijgen."
} }
} }

View file

@ -699,7 +699,15 @@
"api_key_placeholder": "Skriv inn Immich API -tasten", "api_key_placeholder": "Skriv inn Immich API -tasten",
"enable_integration": "Aktiver integrasjon", "enable_integration": "Aktiver integrasjon",
"immich_integration_desc": "Koble til Immich Photo Management Server", "immich_integration_desc": "Koble til Immich Photo Management Server",
"need_help": "Trenger du hjelp til å sette opp dette? \nSjekk ut" "need_help": "Trenger du hjelp til å sette opp dette? \nSjekk ut",
"connection_error": "Feil tilkobling til Immich Server",
"copy_locally": "Kopier bilder lokalt",
"copy_locally_desc": "Kopier bilder til serveren for offline tilgang. \nBruker mer diskplass.",
"error_saving_image": "Feil å lagre bilde",
"integration_already_exists": "En Immich -integrasjon eksisterer allerede. \nDu kan bare ha en integrasjon om gangen.",
"integration_not_found": "Immich -integrasjon ikke funnet. \nOpprett en ny integrasjon.",
"network_error": "Nettverksfeil mens du kobler til Immich -serveren. \nVennligst sjekk tilkoblingen din og prøv igjen.",
"validation_error": "Det oppstod en feil under validering av Immich -integrasjonen. \nVennligst sjekk server -URL -en og API -tasten."
}, },
"recomendations": { "recomendations": {
"address": "Adresse", "address": "Adresse",
@ -712,5 +720,8 @@
"food": "Mat", "food": "Mat",
"miles": "Miles", "miles": "Miles",
"tourism": "Turisme" "tourism": "Turisme"
},
"google_maps": {
"google_maps_integration_desc": "Koble til Google Maps-kontoen din for å få søkeresultater og anbefalinger av høy kvalitet."
} }
} }

View file

@ -669,7 +669,15 @@
"api_key_placeholder": "Wprowadź swój klucz API IMMICH", "api_key_placeholder": "Wprowadź swój klucz API IMMICH",
"enable_integration": "Włącz integrację", "enable_integration": "Włącz integrację",
"immich_integration_desc": "Połącz swój serwer zarządzania zdjęciami Immich", "immich_integration_desc": "Połącz swój serwer zarządzania zdjęciami Immich",
"need_help": "Potrzebujesz pomocy w konfiguracji? \nSprawdź" "need_help": "Potrzebujesz pomocy w konfiguracji? \nSprawdź",
"connection_error": "Błąd łączący się z serwerem Immich",
"copy_locally": "Kopiuj obrazy lokalnie",
"copy_locally_desc": "Skopiuj obrazy na serwer, aby uzyskać dostęp offline. \nWykorzystuje więcej miejsca na dysku.",
"error_saving_image": "Obraz zapisujący błąd",
"integration_already_exists": "Immichu jest już integracja i immich. \nMożesz mieć tylko jedną integrację na raz.",
"integration_not_found": "Nie znaleziono integracji imich. \nUtwórz nową integrację.",
"network_error": "Błąd sieci podczas łączenia się z serwerem IMMICH. \nSprawdź połączenie i spróbuj ponownie.",
"validation_error": "Wystąpił błąd podczas walidacji integracji immicha. \nSprawdź swój adres URL serwera i klawisz API."
}, },
"recomendations": { "recomendations": {
"address": "Adres", "address": "Adres",
@ -712,5 +720,8 @@
"reservation_number": "Numer rezerwacji", "reservation_number": "Numer rezerwacji",
"resort": "Uciec", "resort": "Uciec",
"current_timezone": "Obecna strefa czasowa" "current_timezone": "Obecna strefa czasowa"
},
"google_maps": {
"google_maps_integration_desc": "Połącz swoje konto Google Maps, aby uzyskać wysokiej jakości wyniki wyszukiwania i zalecenia dotyczące lokalizacji."
} }
} }

View file

@ -669,7 +669,15 @@
"api_key_placeholder": "Ange din immich API -nyckel", "api_key_placeholder": "Ange din immich API -nyckel",
"enable_integration": "Aktivera integration", "enable_integration": "Aktivera integration",
"immich_integration_desc": "Anslut din immich fotohanteringsserver", "immich_integration_desc": "Anslut din immich fotohanteringsserver",
"need_help": "Behöver du hjälp med att ställa in detta? \nKolla in" "need_help": "Behöver du hjälp med att ställa in detta? \nKolla in",
"connection_error": "Fel som ansluter till Imchich Server",
"copy_locally": "Kopiera bilder lokalt",
"copy_locally_desc": "Kopiera bilder till servern för offlineåtkomst. \nAnvänder mer diskutrymme.",
"error_saving_image": "Felbesparande bild",
"integration_already_exists": "En immich integration finns redan. \nDu kan bara ha en integration åt gången.",
"integration_not_found": "Imkik integration hittades inte. \nSkapa en ny integration.",
"network_error": "Nätverksfel vid anslutning till den immich servern. \nKontrollera din anslutning och försök igen.",
"validation_error": "Ett fel inträffade vid validering av den immich integrationen. \nKontrollera din server -URL- och API -nyckel."
}, },
"recomendations": { "recomendations": {
"address": "Adress", "address": "Adress",
@ -712,5 +720,8 @@
"edit": "Redigera", "edit": "Redigera",
"edit_lodging": "Redigera logi", "edit_lodging": "Redigera logi",
"current_timezone": "Nuvarande tidszon" "current_timezone": "Nuvarande tidszon"
},
"google_maps": {
"google_maps_integration_desc": "Anslut ditt Google Maps-konto för att få sökresultat och rekommendationer av hög kvalitet."
} }
} }

View file

@ -669,7 +669,15 @@
"api_key_placeholder": "输入您的Immich API密钥", "api_key_placeholder": "输入您的Immich API密钥",
"enable_integration": "启用集成", "enable_integration": "启用集成",
"immich_integration_desc": "连接您的Immich照片管理服务器", "immich_integration_desc": "连接您的Immich照片管理服务器",
"need_help": "需要帮助设置吗?\n查看" "need_help": "需要帮助设置吗?\n查看",
"connection_error": "连接到Immich服务器的错误",
"copy_locally": "在本地复制图像",
"copy_locally_desc": "将图像复制到服务器以进行离线访问。\n使用更多的磁盘空间。",
"error_saving_image": "保存错误的图像",
"integration_already_exists": "Immich整合已经存在。\n您一次只能进行一个集成。",
"integration_not_found": "没有找到Immich整合。\n请创建一个新的集成。",
"network_error": "连接到Immich服务器时的网络错误。\n请检查您的连接然后重试。",
"validation_error": "在验证IMMICH集成时发生了错误。\n请检查您的服务器URL和API键。"
}, },
"recomendations": { "recomendations": {
"address": "地址", "address": "地址",
@ -712,5 +720,8 @@
"reservation_number": "预订号", "reservation_number": "预订号",
"resort": "度假村", "resort": "度假村",
"current_timezone": "当前时区" "current_timezone": "当前时区"
},
"google_maps": {
"google_maps_integration_desc": "连接您的Google Maps帐户以获取高质量的位置搜索结果和建议。"
} }
} }

View file

@ -187,37 +187,57 @@
} }
} }
async function enableImmichIntegration() { function handleImmichError(data: {
if (!immichIntegration?.id) { code: string;
let res = await fetch('/api/integrations/immich/', { details: any;
method: 'POST', message: any;
headers: { error: any;
'Content-Type': 'application/json' server_url: any[];
}, api_key: any[];
body: JSON.stringify(newImmichIntegration) }) {
}); if (data.code === 'immich.connection_failed') {
let data = await res.json(); return `${$t('immich.connection_error')}: ${data.details || data.message}`;
if (res.ok) { } else if (data.code === 'immich.integration_exists') {
addToast('success', $t('immich.immich_enabled')); return $t('immich.integration_already_exists');
immichIntegration = data; } else if (data.code === 'immich.integration_not_found') {
} else { return $t('immich.integration_not_found');
addToast('error', $t('immich.immich_error')); } else if (data.error && data.message) {
} return data.message;
} else { } else {
let res = await fetch(`/api/integrations/immich/${immichIntegration.id}/`, { // Handle validation errors
method: 'PUT', const errors = [];
headers: { if (data.server_url) errors.push(`Server URL: ${data.server_url.join(', ')}`);
'Content-Type': 'application/json' if (data.api_key) errors.push(`API Key: ${data.api_key.join(', ')}`);
}, return errors.length > 0
? `${$t('immich.validation_error')}: ${errors.join('; ')}`
: $t('immich.immich_error');
}
}
async function enableImmichIntegration() {
const isUpdate = !!immichIntegration?.id;
const url = isUpdate
? `/api/integrations/immich/${immichIntegration?.id ?? ''}/`
: '/api/integrations/immich/';
const method = isUpdate ? 'PUT' : 'POST';
try {
const res = await fetch(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(newImmichIntegration) body: JSON.stringify(newImmichIntegration)
}); });
let data = await res.json();
const data = await res.json();
if (res.ok) { if (res.ok) {
addToast('success', $t('immich.immich_updated')); addToast('success', $t(isUpdate ? 'immich.immich_updated' : 'immich.immich_enabled'));
immichIntegration = data; immichIntegration = data;
} else { } else {
addToast('error', $t('immich.immich_error')); addToast('error', handleImmichError(data));
} }
} catch (error) {
addToast('error', $t('immich.network_error'));
} }
} }