mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-07-23 06:49:37 +02:00
Refactor geocoding and integration handling: remove debug print, streamline reverse geocoding logic, and enhance integration response structure
This commit is contained in:
parent
c123231bab
commit
e56335d30f
16 changed files with 95 additions and 46 deletions
|
@ -166,7 +166,6 @@ def is_host_resolvable(hostname: str) -> bool:
|
||||||
|
|
||||||
def reverse_geocode(lat, lon, user):
|
def reverse_geocode(lat, lon, user):
|
||||||
if getattr(settings, 'GOOGLE_MAPS_API_KEY', None):
|
if getattr(settings, 'GOOGLE_MAPS_API_KEY', None):
|
||||||
print("Using Google Maps API for reverse geocoding")
|
|
||||||
return reverse_geocode_google(lat, lon, user)
|
return reverse_geocode_google(lat, lon, user)
|
||||||
return reverse_geocode_osm(lat, lon, user)
|
return reverse_geocode_osm(lat, lon, user)
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ class ReverseGeocodeViewSet(viewsets.ViewSet):
|
||||||
return Response({"error": "An internal error occurred while processing the request"}, status=500)
|
return Response({"error": "An internal error occurred while processing the request"}, status=500)
|
||||||
|
|
||||||
@action(detail=False, methods=['post'])
|
@action(detail=False, methods=['post'])
|
||||||
def mark_visited_region(self, request):
|
def mark_visited_region(self, _):
|
||||||
# searches through all of the users adventures, if the serialized data is_visited, is true, runs reverse geocode on the adventures and if a region is found, marks it as visited. Use the extractIsoCode function to get the region
|
# searches through all of the users adventures, if the serialized data is_visited, is true, runs reverse geocode on the adventures and if a region is found, marks it as visited. Use the extractIsoCode function to get the region
|
||||||
new_region_count = 0
|
new_region_count = 0
|
||||||
new_regions = {}
|
new_regions = {}
|
||||||
|
@ -60,14 +60,13 @@ class ReverseGeocodeViewSet(viewsets.ViewSet):
|
||||||
lon = adventure.longitude
|
lon = adventure.longitude
|
||||||
if not lat or not lon:
|
if not lat or not lon:
|
||||||
continue
|
continue
|
||||||
url = f"https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat={lat}&lon={lon}"
|
|
||||||
headers = {'User-Agent': 'AdventureLog Server'}
|
# Use the existing reverse_geocode function which handles both Google and OSM
|
||||||
response = requests.get(url, headers=headers)
|
data = reverse_geocode(lat, lon, self.request.user)
|
||||||
try:
|
if 'error' in data:
|
||||||
data = response.json()
|
continue
|
||||||
except requests.exceptions.JSONDecodeError:
|
|
||||||
return Response({"error": "Invalid response from geocoding service"}, status=400)
|
extracted_region = extractIsoCode(self.request.user, data)
|
||||||
extracted_region = extractIsoCode(self.request.user,data)
|
|
||||||
if 'error' not in extracted_region:
|
if 'error' not in extracted_region:
|
||||||
region = Region.objects.filter(id=extracted_region['region_id']).first()
|
region = Region.objects.filter(id=extracted_region['region_id']).first()
|
||||||
visited_region = VisitedRegion.objects.filter(region=region, user_id=self.request.user).first()
|
visited_region = VisitedRegion.objects.filter(region=region, user_id=self.request.user).first()
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import os
|
import os
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework import viewsets, status
|
from rest_framework import viewsets, status
|
||||||
|
|
||||||
from .serializers import ImmichIntegrationSerializer
|
from .serializers import ImmichIntegrationSerializer
|
||||||
from .models import ImmichIntegration
|
from .models import ImmichIntegration
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
import requests
|
import requests
|
||||||
from rest_framework.pagination import PageNumberPagination
|
from rest_framework.pagination import PageNumberPagination
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
class IntegrationView(viewsets.ViewSet):
|
class IntegrationView(viewsets.ViewSet):
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
@ -16,15 +16,16 @@ class IntegrationView(viewsets.ViewSet):
|
||||||
RESTful GET method for listing all integrations.
|
RESTful GET method for listing all integrations.
|
||||||
"""
|
"""
|
||||||
immich_integrations = ImmichIntegration.objects.filter(user=request.user)
|
immich_integrations = ImmichIntegration.objects.filter(user=request.user)
|
||||||
|
google_map_integration = settings.GOOGLE_MAPS_API_KEY is not ''
|
||||||
|
|
||||||
return Response(
|
return Response(
|
||||||
{
|
{
|
||||||
'immich': immich_integrations.exists()
|
'immich': immich_integrations.exists(),
|
||||||
|
'google_maps': google_map_integration
|
||||||
},
|
},
|
||||||
status=status.HTTP_200_OK
|
status=status.HTTP_200_OK
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class StandardResultsSetPagination(PageNumberPagination):
|
class StandardResultsSetPagination(PageNumberPagination):
|
||||||
page_size = 25
|
page_size = 25
|
||||||
page_size_query_param = 'page_size'
|
page_size_query_param = 'page_size'
|
||||||
|
|
|
@ -61,6 +61,7 @@ class Command(BaseCommand):
|
||||||
return
|
return
|
||||||
elif os.path.getsize(countries_json_path) == 0:
|
elif os.path.getsize(countries_json_path) == 0:
|
||||||
self.stdout.write(self.style.ERROR('countries+regions+states.json is empty'))
|
self.stdout.write(self.style.ERROR('countries+regions+states.json is empty'))
|
||||||
|
return
|
||||||
elif Country.objects.count() == 0 or Region.objects.count() == 0 or City.objects.count() == 0:
|
elif Country.objects.count() == 0 or Region.objects.count() == 0 or City.objects.count() == 0:
|
||||||
self.stdout.write(self.style.WARNING('Some region data is missing. Re-importing all data.'))
|
self.stdout.write(self.style.WARNING('Some region data is missing. Re-importing all data.'))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -7,11 +7,19 @@
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
let modal: HTMLDialogElement;
|
let modal: HTMLDialogElement;
|
||||||
|
|
||||||
onMount(() => {
|
let integrations: Record<string, boolean> | null = null;
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
modal = document.getElementById('about_modal') as HTMLDialogElement;
|
modal = document.getElementById('about_modal') as HTMLDialogElement;
|
||||||
if (modal) {
|
if (modal) {
|
||||||
modal.showModal();
|
modal.showModal();
|
||||||
}
|
}
|
||||||
|
const response = await fetch('/api/integrations');
|
||||||
|
if (response.ok) {
|
||||||
|
integrations = await response.json();
|
||||||
|
} else {
|
||||||
|
integrations = null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
|
@ -90,18 +98,38 @@
|
||||||
<h3 class="text-lg font-semibold text-gray-800 dark:text-white">
|
<h3 class="text-lg font-semibold text-gray-800 dark:text-white">
|
||||||
{$t('about.oss_attributions')}
|
{$t('about.oss_attributions')}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
{#if integrations && integrations?.google_maps}
|
||||||
{$t('about.nominatim_1')}
|
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||||
<a
|
{$t('about.nominatim_1')}
|
||||||
href="https://operations.osmfoundation.org/policies/nominatim/"
|
<a
|
||||||
target="_blank"
|
href="https://developers.google.com/maps/terms"
|
||||||
rel="noopener noreferrer"
|
target="_blank"
|
||||||
class="text-primary hover:underline"
|
rel="noopener noreferrer"
|
||||||
>
|
class="text-primary hover:underline"
|
||||||
OpenStreetMap
|
>
|
||||||
</a>
|
Google Maps
|
||||||
. {$t('about.nominatim_2')}
|
</a>
|
||||||
</p>
|
.
|
||||||
|
</p>
|
||||||
|
{:else if integrations && !integrations?.google_maps}
|
||||||
|
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||||
|
{$t('about.nominatim_1')}
|
||||||
|
<a
|
||||||
|
href="https://operations.osmfoundation.org/policies/nominatim/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="text-primary hover:underline"
|
||||||
|
>
|
||||||
|
OpenStreetMap
|
||||||
|
</a>
|
||||||
|
. {$t('about.nominatim_2')}
|
||||||
|
</p>
|
||||||
|
{:else}
|
||||||
|
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||||
|
{$t('about.generic_attributions')}
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">{$t('about.other_attributions')}</p>
|
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">{$t('about.other_attributions')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
"nominatim_2": "Deren Daten sind unter der ODbL-Lizenz lizenziert.",
|
"nominatim_2": "Deren Daten sind unter der ODbL-Lizenz lizenziert.",
|
||||||
"oss_attributions": "Open Source Quellenangaben",
|
"oss_attributions": "Open Source Quellenangaben",
|
||||||
"other_attributions": "Weitere Hinweise finden Sie in der README-Datei.",
|
"other_attributions": "Weitere Hinweise finden Sie in der README-Datei.",
|
||||||
"source_code": "Quellcode"
|
"source_code": "Quellcode",
|
||||||
|
"generic_attributions": "Melden Sie sich bei Adventurelog an, um Zuschreibungen für aktivierte Integrationen und Dienste anzuzeigen."
|
||||||
},
|
},
|
||||||
"adventures": {
|
"adventures": {
|
||||||
"activities": {
|
"activities": {
|
||||||
|
@ -267,7 +268,8 @@
|
||||||
"sun_times": "Sonnenzeiten",
|
"sun_times": "Sonnenzeiten",
|
||||||
"sunrise": "Sonnenaufgang",
|
"sunrise": "Sonnenaufgang",
|
||||||
"sunset": "Sonnenuntergang",
|
"sunset": "Sonnenuntergang",
|
||||||
"timed": "Zeitlich abgestimmt"
|
"timed": "Zeitlich abgestimmt",
|
||||||
|
"distance": "Distanz"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"desc_1": "Entdecken, planen und erkunden Sie mühelos",
|
"desc_1": "Entdecken, planen und erkunden Sie mühelos",
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
"nominatim_1": "Location Search and Geocoding is provided by",
|
"nominatim_1": "Location Search and Geocoding is provided by",
|
||||||
"nominatim_2": "Their data is liscensed under the ODbL license.",
|
"nominatim_2": "Their data is liscensed under the ODbL license.",
|
||||||
"other_attributions": "Additional attributions can be found in the README file.",
|
"other_attributions": "Additional attributions can be found in the README file.",
|
||||||
|
"generic_attributions": "Login to AdventureLog to view attributions for enabled integrations and services.",
|
||||||
"close": "Close"
|
"close": "Close"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
|
|
|
@ -42,7 +42,8 @@
|
||||||
"nominatim_1": "La búsqueda de ubicaciones y geocodificación es proporcionada por",
|
"nominatim_1": "La búsqueda de ubicaciones y geocodificación es proporcionada por",
|
||||||
"nominatim_2": "Sus datos están licenciados bajo la licencia ODbL.",
|
"nominatim_2": "Sus datos están licenciados bajo la licencia ODbL.",
|
||||||
"other_attributions": "Atribuciones adicionales se pueden encontrar en el archivo README.",
|
"other_attributions": "Atribuciones adicionales se pueden encontrar en el archivo README.",
|
||||||
"close": "Cerrar"
|
"close": "Cerrar",
|
||||||
|
"generic_attributions": "Inicie sesión en AdventurElog para ver las atribuciones para integraciones y servicios habilitados."
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"hero_1": "Descubre las Aventuras Más Emocionantes del Mundo",
|
"hero_1": "Descubre las Aventuras Más Emocionantes del Mundo",
|
||||||
|
@ -315,7 +316,8 @@
|
||||||
"sun_times": "Sol Times",
|
"sun_times": "Sol Times",
|
||||||
"sunrise": "Amanecer",
|
"sunrise": "Amanecer",
|
||||||
"sunset": "Atardecer",
|
"sunset": "Atardecer",
|
||||||
"timed": "Cronometrado"
|
"timed": "Cronometrado",
|
||||||
|
"distance": "Distancia"
|
||||||
},
|
},
|
||||||
"worldtravel": {
|
"worldtravel": {
|
||||||
"all": "Todo",
|
"all": "Todo",
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
"nominatim_2": "Leurs données sont sous licence ODbL.",
|
"nominatim_2": "Leurs données sont sous licence ODbL.",
|
||||||
"oss_attributions": "Attributions Open Source",
|
"oss_attributions": "Attributions Open Source",
|
||||||
"other_attributions": "Des attributions supplémentaires peuvent être trouvées dans le fichier README.",
|
"other_attributions": "Des attributions supplémentaires peuvent être trouvées dans le fichier README.",
|
||||||
"source_code": "Code source"
|
"source_code": "Code source",
|
||||||
|
"generic_attributions": "Connectez-vous à AdventureLog pour afficher les attributions pour les intégrations et services activés."
|
||||||
},
|
},
|
||||||
"adventures": {
|
"adventures": {
|
||||||
"activities": {
|
"activities": {
|
||||||
|
@ -267,7 +268,8 @@
|
||||||
"sun_times": "Temps du soleil",
|
"sun_times": "Temps du soleil",
|
||||||
"sunrise": "Lever du soleil",
|
"sunrise": "Lever du soleil",
|
||||||
"sunset": "Coucher de soleil",
|
"sunset": "Coucher de soleil",
|
||||||
"timed": "Chronométré"
|
"timed": "Chronométré",
|
||||||
|
"distance": "Distance"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"desc_1": "Découvrez, planifiez et explorez en toute simplicité",
|
"desc_1": "Découvrez, planifiez et explorez en toute simplicité",
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
"nominatim_2": "I loro dati sono concessi in licenza con la licenza ODbL.",
|
"nominatim_2": "I loro dati sono concessi in licenza con la licenza ODbL.",
|
||||||
"oss_attributions": "Attribuzioni Open Source",
|
"oss_attributions": "Attribuzioni Open Source",
|
||||||
"other_attributions": "Ulteriori attribuzioni possono essere trovate nel file README.",
|
"other_attributions": "Ulteriori attribuzioni possono essere trovate nel file README.",
|
||||||
"source_code": "Codice sorgente"
|
"source_code": "Codice sorgente",
|
||||||
|
"generic_attributions": "Accedi a AdventureLog per visualizzare le attribuzioni per integrazioni e servizi abilitati."
|
||||||
},
|
},
|
||||||
"adventures": {
|
"adventures": {
|
||||||
"activities": {
|
"activities": {
|
||||||
|
@ -267,7 +268,8 @@
|
||||||
"sun_times": "Sun Times",
|
"sun_times": "Sun Times",
|
||||||
"sunrise": "Alba",
|
"sunrise": "Alba",
|
||||||
"sunset": "Tramonto",
|
"sunset": "Tramonto",
|
||||||
"timed": "A tempo"
|
"timed": "A tempo",
|
||||||
|
"distance": "Distanza"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"desc_1": "Scopri, pianifica ed esplora con facilità",
|
"desc_1": "Scopri, pianifica ed esplora con facilità",
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
"nominatim_2": "데이터는 ODbL 라이선스가 적용됩니다.",
|
"nominatim_2": "데이터는 ODbL 라이선스가 적용됩니다.",
|
||||||
"oss_attributions": "오픈 소스 속성",
|
"oss_attributions": "오픈 소스 속성",
|
||||||
"other_attributions": "추가 속성은 README 파일에서 찾을 수 있습니다.",
|
"other_attributions": "추가 속성은 README 파일에서 찾을 수 있습니다.",
|
||||||
"source_code": "소스 코드"
|
"source_code": "소스 코드",
|
||||||
|
"generic_attributions": "Adventurelog에 로그인하여 활성화 된 통합 및 서비스에 대한 속성을보십시오."
|
||||||
},
|
},
|
||||||
"adventures": {
|
"adventures": {
|
||||||
"actions": "행동",
|
"actions": "행동",
|
||||||
|
@ -267,7 +268,8 @@
|
||||||
"sun_times": "태양 시간",
|
"sun_times": "태양 시간",
|
||||||
"sunrise": "해돋이",
|
"sunrise": "해돋이",
|
||||||
"sunset": "일몰",
|
"sunset": "일몰",
|
||||||
"timed": "시간이 정해졌습니다"
|
"timed": "시간이 정해졌습니다",
|
||||||
|
"distance": "거리"
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"both_passwords_required": "두 암호 모두 필요합니다",
|
"both_passwords_required": "두 암호 모두 필요합니다",
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
"nominatim_2": "Hun gegevens zijn in licentie gegeven onder de ODbL-licentie.",
|
"nominatim_2": "Hun gegevens zijn in licentie gegeven onder de ODbL-licentie.",
|
||||||
"oss_attributions": "Open source gebruik",
|
"oss_attributions": "Open source gebruik",
|
||||||
"other_attributions": "Aanvullende vermeldingen zijn te vinden in het README-bestand.",
|
"other_attributions": "Aanvullende vermeldingen zijn te vinden in het README-bestand.",
|
||||||
"source_code": "Broncode"
|
"source_code": "Broncode",
|
||||||
|
"generic_attributions": "Log in op AdventUrelog om attributies te bekijken voor ingeschakelde integraties en services."
|
||||||
},
|
},
|
||||||
"adventures": {
|
"adventures": {
|
||||||
"activities": {
|
"activities": {
|
||||||
|
@ -267,7 +268,8 @@
|
||||||
"sun_times": "Zonnetijden",
|
"sun_times": "Zonnetijden",
|
||||||
"sunrise": "Zonsopgang",
|
"sunrise": "Zonsopgang",
|
||||||
"sunset": "Zonsondergang",
|
"sunset": "Zonsondergang",
|
||||||
"timed": "Getimed"
|
"timed": "Getimed",
|
||||||
|
"distance": "Afstand"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"desc_1": "Ontdek, plan en verken met gemak",
|
"desc_1": "Ontdek, plan en verken met gemak",
|
||||||
|
|
|
@ -42,7 +42,8 @@
|
||||||
"nominatim_1": "Stedsøk og geokoding leveres av",
|
"nominatim_1": "Stedsøk og geokoding leveres av",
|
||||||
"nominatim_2": "Deres data er lisensiert under ODbL-lisensen.",
|
"nominatim_2": "Deres data er lisensiert under ODbL-lisensen.",
|
||||||
"other_attributions": "Ytterligere attribusjoner finnes i README-filen.",
|
"other_attributions": "Ytterligere attribusjoner finnes i README-filen.",
|
||||||
"close": "Lukk"
|
"close": "Lukk",
|
||||||
|
"generic_attributions": "Logg inn på Adventurelog for å se attribusjoner for aktiverte integrasjoner og tjenester."
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"hero_1": "Oppdag verdens mest spennende eventyr",
|
"hero_1": "Oppdag verdens mest spennende eventyr",
|
||||||
|
@ -315,7 +316,8 @@
|
||||||
"sun_times": "Soltider",
|
"sun_times": "Soltider",
|
||||||
"sunrise": "Soloppgang",
|
"sunrise": "Soloppgang",
|
||||||
"sunset": "Solnedgang",
|
"sunset": "Solnedgang",
|
||||||
"timed": "Tidsbestemt"
|
"timed": "Tidsbestemt",
|
||||||
|
"distance": "Avstand"
|
||||||
},
|
},
|
||||||
"worldtravel": {
|
"worldtravel": {
|
||||||
"country_list": "Liste over land",
|
"country_list": "Liste over land",
|
||||||
|
|
|
@ -42,7 +42,8 @@
|
||||||
"nominatim_1": "Wyszukiwanie lokalizacji i geokodowanie zapewnia",
|
"nominatim_1": "Wyszukiwanie lokalizacji i geokodowanie zapewnia",
|
||||||
"nominatim_2": "Ich dane są licencjonowane na licencji ODbL.",
|
"nominatim_2": "Ich dane są licencjonowane na licencji ODbL.",
|
||||||
"other_attributions": "Dodatkowe atrybucje można znaleźć w pliku README.",
|
"other_attributions": "Dodatkowe atrybucje można znaleźć w pliku README.",
|
||||||
"close": "Zamknij"
|
"close": "Zamknij",
|
||||||
|
"generic_attributions": "Zaloguj się do Adventurelog, aby wyświetlić atrybucje dla włączonych integracji i usług."
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"hero_1": "Odkryj najbardziej ekscytujące podróże na świecie",
|
"hero_1": "Odkryj najbardziej ekscytujące podróże na świecie",
|
||||||
|
@ -315,7 +316,8 @@
|
||||||
"sun_times": "Czasy słońca",
|
"sun_times": "Czasy słońca",
|
||||||
"sunrise": "Wschód słońca",
|
"sunrise": "Wschód słońca",
|
||||||
"sunset": "Zachód słońca",
|
"sunset": "Zachód słońca",
|
||||||
"timed": "Czas"
|
"timed": "Czas",
|
||||||
|
"distance": "Dystans"
|
||||||
},
|
},
|
||||||
"worldtravel": {
|
"worldtravel": {
|
||||||
"country_list": "Lista krajów",
|
"country_list": "Lista krajów",
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
"nominatim_2": "Deras data är licensierad under ODbL-licensen.",
|
"nominatim_2": "Deras data är licensierad under ODbL-licensen.",
|
||||||
"oss_attributions": "Tillskrivningar med öppen källkod",
|
"oss_attributions": "Tillskrivningar med öppen källkod",
|
||||||
"other_attributions": "Ytterligare attributioner finns i README-filen.",
|
"other_attributions": "Ytterligare attributioner finns i README-filen.",
|
||||||
"source_code": "Källkod"
|
"source_code": "Källkod",
|
||||||
|
"generic_attributions": "Logga in på AdventureLog för att visa attribut för aktiverade integrationer och tjänster."
|
||||||
},
|
},
|
||||||
"adventures": {
|
"adventures": {
|
||||||
"activities": {
|
"activities": {
|
||||||
|
@ -267,7 +268,8 @@
|
||||||
"sun_times": "Soltider",
|
"sun_times": "Soltider",
|
||||||
"sunrise": "Soluppgång",
|
"sunrise": "Soluppgång",
|
||||||
"sunset": "Solnedgång",
|
"sunset": "Solnedgång",
|
||||||
"timed": "Tidsinställd"
|
"timed": "Tidsinställd",
|
||||||
|
"distance": "Avstånd"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"desc_1": "Upptäck, planera och utforska med lätthet",
|
"desc_1": "Upptäck, planera och utforska med lätthet",
|
||||||
|
|
|
@ -42,7 +42,8 @@
|
||||||
"oss_attributions": "开源声明",
|
"oss_attributions": "开源声明",
|
||||||
"other_attributions": "其他声明可以在 README 文件中找到。",
|
"other_attributions": "其他声明可以在 README 文件中找到。",
|
||||||
"source_code": "源代码",
|
"source_code": "源代码",
|
||||||
"close": "关闭"
|
"close": "关闭",
|
||||||
|
"generic_attributions": "登录到AdventureLog以查看启用集成和服务的归因。"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"desc_1": "轻松发现、规划和探索",
|
"desc_1": "轻松发现、规划和探索",
|
||||||
|
@ -315,7 +316,8 @@
|
||||||
"sun_times": "阳光时代",
|
"sun_times": "阳光时代",
|
||||||
"sunrise": "日出",
|
"sunrise": "日出",
|
||||||
"sunset": "日落",
|
"sunset": "日落",
|
||||||
"timed": "时间"
|
"timed": "时间",
|
||||||
|
"distance": "距离"
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"forgot_password": "忘记密码?",
|
"forgot_password": "忘记密码?",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue