WIP save Spotify login progress
This commit is contained in:
@@ -24,7 +24,7 @@ export default function LoginScreen({ navigation }) {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
// Direct Spotify App Client ID
|
// Direct Spotify App Client ID
|
||||||
const SPOTIFY_CLIENT_ID = "7fa1e7acbf7e44f18bf28d74f14fb9cb";
|
const SPOTIFY_CLIENT_ID = process.env.EXPO_PUBLIC_SPOTIFY_CLIENT_ID || "7fa1e7acbf7e44f18bf28d74f14fb9cb";
|
||||||
|
|
||||||
// Configure Dynamic Redirect URI
|
// Configure Dynamic Redirect URI
|
||||||
const redirectUri = makeRedirectUri({
|
const redirectUri = makeRedirectUri({
|
||||||
@@ -42,6 +42,13 @@ export default function LoginScreen({ navigation }) {
|
|||||||
discovery
|
discovery
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("[SpotifyAuthDebug] Platform:", Platform.OS);
|
||||||
|
console.log("[SpotifyAuthDebug] redirectUri:", redirectUri);
|
||||||
|
console.log("[SpotifyAuthDebug] Client ID exists in env:", Boolean(process.env.EXPO_PUBLIC_SPOTIFY_CLIENT_ID));
|
||||||
|
console.log("[SpotifyAuthDebug] Scopes being requested:", ['user-read-email', 'user-read-private', 'playlist-modify-public', 'playlist-modify-private']);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const showSpotifyLoginFailure = () => {
|
const showSpotifyLoginFailure = () => {
|
||||||
Alert.alert('Erro de Autenticação', 'Não foi possível iniciar sessão com Spotify. Tenta novamente ou usa login normal.');
|
Alert.alert('Erro de Autenticação', 'Não foi possível iniciar sessão com Spotify. Tenta novamente ou usa login normal.');
|
||||||
};
|
};
|
||||||
@@ -49,9 +56,29 @@ export default function LoginScreen({ navigation }) {
|
|||||||
// Handle Spotify OAuth Response
|
// Handle Spotify OAuth Response
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (response) {
|
if (response) {
|
||||||
console.log("SPOTIFY_AUTH_RESULT:", response);
|
// Redact tokens/codes from logs to protect secrets
|
||||||
|
const res = response as any;
|
||||||
|
const cleanResponse = {
|
||||||
|
...res,
|
||||||
|
authentication: res.authentication ? { ...res.authentication, accessToken: '[REDACTED]', refreshToken: '[REDACTED]' } : undefined,
|
||||||
|
params: res.params ? {
|
||||||
|
...res.params,
|
||||||
|
access_token: res.params.access_token ? '[REDACTED]' : undefined,
|
||||||
|
refresh_token: res.params.refresh_token ? '[REDACTED]' : undefined,
|
||||||
|
code: res.params.code ? '[REDACTED_CODE]' : undefined,
|
||||||
|
} : undefined
|
||||||
|
};
|
||||||
|
console.log("[SpotifyAuthDebug] 2. Full AuthSession response object (sanitized):", JSON.stringify(cleanResponse, null, 2));
|
||||||
|
console.log("[SpotifyAuthDebug] 3. response.type:", response.type);
|
||||||
|
console.log("[SpotifyAuthDebug] 4. response.error:", res.error || "none");
|
||||||
|
console.log("[SpotifyAuthDebug] 5. response.params.error:", res.params?.error || "none");
|
||||||
|
console.log("[SpotifyAuthDebug] 5. response.params.error_description:", res.params?.error_description || "none");
|
||||||
|
console.log("[SpotifyAuthDebug] 6. Received authorization code:", Boolean(res.params?.code));
|
||||||
|
console.log("[SpotifyAuthDebug] 6. Received access token:", Boolean(res.params?.access_token || res.authentication?.accessToken));
|
||||||
|
|
||||||
if (response.type === 'success') {
|
if (response.type === 'success') {
|
||||||
const { code } = response.params;
|
const { code } = res.params;
|
||||||
|
console.log("[SpotifyAuthDebug] Stage: After redirecting back - Success received.");
|
||||||
console.log("[LoginScreen] Spotify auth success:", {
|
console.log("[LoginScreen] Spotify auth success:", {
|
||||||
redirectUri,
|
redirectUri,
|
||||||
clientIdExists: Boolean(SPOTIFY_CLIENT_ID),
|
clientIdExists: Boolean(SPOTIFY_CLIENT_ID),
|
||||||
@@ -61,15 +88,19 @@ export default function LoginScreen({ navigation }) {
|
|||||||
flow: 'authorization_code_pkce',
|
flow: 'authorization_code_pkce',
|
||||||
});
|
});
|
||||||
exchangeCodeForTokens(code);
|
exchangeCodeForTokens(code);
|
||||||
} else if (response.type === 'error') {
|
} else {
|
||||||
console.warn('[LoginScreen] Spotify OAuth response error:', response.error?.message || response.error);
|
console.warn("[SpotifyAuthDebug] Stage: After redirecting back - Auth session ended without success status. Type:", response.type);
|
||||||
Alert.alert('Erro de Autenticação', response.error?.message || 'Falha ao logar com o Spotify');
|
if (response.type === 'error') {
|
||||||
|
console.warn('[LoginScreen] Spotify OAuth response error:', res.error?.message || res.error);
|
||||||
|
Alert.alert('Erro de Autenticação', res.error?.message || 'Falha ao logar com o Spotify');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [response]);
|
}, [response]);
|
||||||
|
|
||||||
const exchangeCodeForTokens = async (code: string) => {
|
const exchangeCodeForTokens = async (code: string) => {
|
||||||
if (!request?.codeVerifier) {
|
if (!request?.codeVerifier) {
|
||||||
|
console.warn('[SpotifyAuthDebug] Stage: Token Exchange Failed (Missing PKCE code verifier)');
|
||||||
console.warn('[LoginScreen] Missing Spotify PKCE code verifier:', {
|
console.warn('[LoginScreen] Missing Spotify PKCE code verifier:', {
|
||||||
redirectUri,
|
redirectUri,
|
||||||
clientIdExists: Boolean(SPOTIFY_CLIENT_ID),
|
clientIdExists: Boolean(SPOTIFY_CLIENT_ID),
|
||||||
@@ -82,6 +113,7 @@ export default function LoginScreen({ navigation }) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
console.log('[SpotifyAuthDebug] Stage: Performing Token Exchange');
|
||||||
console.log('[LoginScreen] Spotify token exchange start:', {
|
console.log('[LoginScreen] Spotify token exchange start:', {
|
||||||
redirectUri,
|
redirectUri,
|
||||||
clientIdExists: Boolean(SPOTIFY_CLIENT_ID),
|
clientIdExists: Boolean(SPOTIFY_CLIENT_ID),
|
||||||
@@ -114,6 +146,7 @@ export default function LoginScreen({ navigation }) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!tokenResponse.ok) {
|
if (!tokenResponse.ok) {
|
||||||
|
console.warn('[SpotifyAuthDebug] Stage: Token Exchange Failed (HTTP Error)');
|
||||||
console.warn('[LoginScreen] Spotify token exchange failed:', {
|
console.warn('[LoginScreen] Spotify token exchange failed:', {
|
||||||
httpStatus: tokenResponse.status,
|
httpStatus: tokenResponse.status,
|
||||||
responseBody: tokenResponseText,
|
responseBody: tokenResponseText,
|
||||||
@@ -126,6 +159,7 @@ export default function LoginScreen({ navigation }) {
|
|||||||
try {
|
try {
|
||||||
tokenResult = JSON.parse(tokenResponseText);
|
tokenResult = JSON.parse(tokenResponseText);
|
||||||
} catch (parseError) {
|
} catch (parseError) {
|
||||||
|
console.warn('[SpotifyAuthDebug] Stage: Token Exchange Failed (JSON Parse Error)');
|
||||||
console.warn('[LoginScreen] Spotify token response JSON parse failed:', parseError);
|
console.warn('[LoginScreen] Spotify token response JSON parse failed:', parseError);
|
||||||
showSpotifyLoginFailure();
|
showSpotifyLoginFailure();
|
||||||
return;
|
return;
|
||||||
@@ -139,6 +173,7 @@ export default function LoginScreen({ navigation }) {
|
|||||||
await setSpotifyRefreshToken(tokenResult.refresh_token);
|
await setSpotifyRefreshToken(tokenResult.refresh_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("[SpotifyAuthDebug] Stage: Fetching Spotify Profile");
|
||||||
console.log("SPOTIFY_PROFILE_FETCH_START");
|
console.log("SPOTIFY_PROFILE_FETCH_START");
|
||||||
const profileRes = await fetch('https://api.spotify.com/v1/me', {
|
const profileRes = await fetch('https://api.spotify.com/v1/me', {
|
||||||
headers: { Authorization: `Bearer ${tokenResult.access_token}` }
|
headers: { Authorization: `Bearer ${tokenResult.access_token}` }
|
||||||
@@ -152,6 +187,7 @@ export default function LoginScreen({ navigation }) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!profileRes.ok) {
|
if (!profileRes.ok) {
|
||||||
|
console.warn('[SpotifyAuthDebug] Stage: Fetching Spotify Profile Failed (HTTP Error)');
|
||||||
console.warn('[LoginScreen] Spotify profile fetch failed:', {
|
console.warn('[LoginScreen] Spotify profile fetch failed:', {
|
||||||
httpStatus: profileRes.status,
|
httpStatus: profileRes.status,
|
||||||
responseBody: profileText,
|
responseBody: profileText,
|
||||||
@@ -164,11 +200,13 @@ export default function LoginScreen({ navigation }) {
|
|||||||
try {
|
try {
|
||||||
profile = JSON.parse(profileText);
|
profile = JSON.parse(profileText);
|
||||||
} catch (parseError) {
|
} catch (parseError) {
|
||||||
|
console.warn('[SpotifyAuthDebug] Stage: Fetching Spotify Profile Failed (JSON Parse Error)');
|
||||||
console.warn('[LoginScreen] Spotify profile JSON parse failed:', parseError);
|
console.warn('[LoginScreen] Spotify profile JSON parse failed:', parseError);
|
||||||
showSpotifyLoginFailure();
|
showSpotifyLoginFailure();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("[SpotifyAuthDebug] Stage: Completing Supabase Auth and updating metadata");
|
||||||
console.log("SPOTIFY_PROFILE_NAME:", profile.display_name);
|
console.log("SPOTIFY_PROFILE_NAME:", profile.display_name);
|
||||||
console.log("SPOTIFY_PROFILE_EMAIL_EXISTS:", !!profile.email);
|
console.log("SPOTIFY_PROFILE_EMAIL_EXISTS:", !!profile.email);
|
||||||
console.log("SPOTIFY_USER_ID:", profile.id);
|
console.log("SPOTIFY_USER_ID:", profile.id);
|
||||||
@@ -277,6 +315,8 @@ export default function LoginScreen({ navigation }) {
|
|||||||
|
|
||||||
const handleSpotifyLogin = async () => {
|
const handleSpotifyLogin = async () => {
|
||||||
try {
|
try {
|
||||||
|
console.log("[SpotifyAuthDebug] 1. Exact redirectUri at login press:", redirectUri);
|
||||||
|
console.log("[SpotifyAuthDebug] Stage: Before Spotify redirects back (Launching Spotify browser...)");
|
||||||
console.log("[LoginScreen] Spotify login start:", {
|
console.log("[LoginScreen] Spotify login start:", {
|
||||||
redirectUri,
|
redirectUri,
|
||||||
clientIdExists: Boolean(SPOTIFY_CLIENT_ID),
|
clientIdExists: Boolean(SPOTIFY_CLIENT_ID),
|
||||||
@@ -285,7 +325,9 @@ export default function LoginScreen({ navigation }) {
|
|||||||
flow: 'authorization_code_pkce',
|
flow: 'authorization_code_pkce',
|
||||||
});
|
});
|
||||||
await promptAsync();
|
await promptAsync();
|
||||||
|
console.log("[SpotifyAuthDebug] Browser promptAsync promise resolved.");
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
|
console.warn('[SpotifyAuthDebug] Failure before Spotify redirects back (Error during promptAsync):', e?.message || e);
|
||||||
console.warn('🚀 [LoginScreen] OAuth Error:', e?.message || e);
|
console.warn('🚀 [LoginScreen] OAuth Error:', e?.message || e);
|
||||||
showSpotifyLoginFailure();
|
showSpotifyLoginFailure();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export default function RegisterScreen({ navigation }) {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
// Direct Spotify App Client ID
|
// Direct Spotify App Client ID
|
||||||
const SPOTIFY_CLIENT_ID = "7fa1e7acbf7e44f18bf28d74f14fb9cb";
|
const SPOTIFY_CLIENT_ID = process.env.EXPO_PUBLIC_SPOTIFY_CLIENT_ID || "7fa1e7acbf7e44f18bf28d74f14fb9cb";
|
||||||
|
|
||||||
// Configure Dynamic Redirect URI
|
// Configure Dynamic Redirect URI
|
||||||
const redirectUri = makeRedirectUri({
|
const redirectUri = makeRedirectUri({
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export default function NewTripScreen({ navigation }) {
|
|||||||
|
|
||||||
if (providerToken) {
|
if (providerToken) {
|
||||||
// Proactively check if token is valid, or refresh it
|
// Proactively check if token is valid, or refresh it
|
||||||
console.log("Validating Spotify token...");
|
console.log("Validating Spotify token via GET /v1/me...");
|
||||||
let testRes = await fetch('https://api.spotify.com/v1/me', {
|
let testRes = await fetch('https://api.spotify.com/v1/me', {
|
||||||
headers: { Authorization: `Bearer ${providerToken}` }
|
headers: { Authorization: `Bearer ${providerToken}` }
|
||||||
});
|
});
|
||||||
@@ -90,19 +90,17 @@ export default function NewTripScreen({ navigation }) {
|
|||||||
const newToken = await refreshSpotifyToken();
|
const newToken = await refreshSpotifyToken();
|
||||||
if (newToken) {
|
if (newToken) {
|
||||||
providerToken = newToken;
|
providerToken = newToken;
|
||||||
|
console.log("Spotify token refreshed successfully!");
|
||||||
} else {
|
} else {
|
||||||
console.log("Failed to refresh Spotify token.");
|
console.log("Failed to refresh Spotify token.");
|
||||||
providerToken = null;
|
providerToken = null;
|
||||||
}
|
}
|
||||||
} else if (!testRes.ok) {
|
} else if (!testRes.ok) {
|
||||||
const testErr = await testRes.text();
|
const testErr = await testRes.text();
|
||||||
if (testRes.status === 403 || testErr.toLowerCase().includes('active premium subscription required')) {
|
console.warn("Spotify validation request failed on GET /v1/me:", testRes.status, testErr);
|
||||||
spotifyPremiumRequired = true;
|
|
||||||
console.warn("Spotify validation skipped due to expected Premium limitation:", testRes.status, testErr);
|
|
||||||
} else {
|
|
||||||
console.warn("Spotify validation request failed:", testRes.status, testErr);
|
|
||||||
}
|
|
||||||
providerToken = null;
|
providerToken = null;
|
||||||
|
} else {
|
||||||
|
console.log("Spotify token is valid (GET /v1/me returned 200 OK).");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +152,10 @@ export default function NewTripScreen({ navigation }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// D. Create empty playlist
|
// D. Create empty playlist
|
||||||
|
console.log("[SpotifyPlaylistDebug] playlist create request started");
|
||||||
|
console.log("[SpotifyPlaylistDebug] userId exists:", Boolean(spotifyUserId));
|
||||||
|
console.log("[SpotifyPlaylistDebug] access token exists:", Boolean(providerToken));
|
||||||
|
|
||||||
const createPlaylistRes = await fetch(`https://api.spotify.com/v1/users/${spotifyUserId}/playlists`, {
|
const createPlaylistRes = await fetch(`https://api.spotify.com/v1/users/${spotifyUserId}/playlists`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -166,7 +168,21 @@ export default function NewTripScreen({ navigation }) {
|
|||||||
public: false
|
public: false
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
const playlistData = await safeParseJson(createPlaylistRes, 'CreatePlaylist');
|
|
||||||
|
console.log("[SpotifyPlaylistDebug] create playlist HTTP status:", createPlaylistRes.status);
|
||||||
|
const createPlaylistResText = await createPlaylistRes.text();
|
||||||
|
if (!createPlaylistRes.ok) {
|
||||||
|
console.log("[SpotifyPlaylistDebug] create playlist response body if failed:", createPlaylistResText);
|
||||||
|
throw new Error(`Spotify API returned status ${createPlaylistRes.status} for CreatePlaylist: ${createPlaylistResText.substring(0, 150)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let playlistData: any;
|
||||||
|
try {
|
||||||
|
playlistData = JSON.parse(createPlaylistResText);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`Failed to parse JSON response for CreatePlaylist: ${createPlaylistResText.substring(0, 150)}`);
|
||||||
|
}
|
||||||
|
|
||||||
if (!playlistData.id) throw new Error('Could not create playlist');
|
if (!playlistData.id) throw new Error('Could not create playlist');
|
||||||
const playlistId = playlistData.id;
|
const playlistId = playlistData.id;
|
||||||
generatedPlaylistUrl = playlistData.external_urls.spotify;
|
generatedPlaylistUrl = playlistData.external_urls.spotify;
|
||||||
@@ -225,6 +241,8 @@ export default function NewTripScreen({ navigation }) {
|
|||||||
const chunkSize = 100;
|
const chunkSize = 100;
|
||||||
for (let i = 0; i < trackUris.length; i += chunkSize) {
|
for (let i = 0; i < trackUris.length; i += chunkSize) {
|
||||||
const chunk = trackUris.slice(i, i + chunkSize);
|
const chunk = trackUris.slice(i, i + chunkSize);
|
||||||
|
|
||||||
|
console.log("[SpotifyPlaylistDebug] Add tracks request started for chunk:", i / chunkSize + 1);
|
||||||
const addTracksRes = await fetch(`https://api.spotify.com/v1/playlists/${playlistId}/tracks`, {
|
const addTracksRes = await fetch(`https://api.spotify.com/v1/playlists/${playlistId}/tracks`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -233,8 +251,11 @@ export default function NewTripScreen({ navigation }) {
|
|||||||
},
|
},
|
||||||
body: JSON.stringify({ uris: chunk })
|
body: JSON.stringify({ uris: chunk })
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log("[SpotifyPlaylistDebug] add tracks HTTP status:", addTracksRes.status);
|
||||||
if (!addTracksRes.ok) {
|
if (!addTracksRes.ok) {
|
||||||
const addTracksErr = await addTracksRes.text();
|
const addTracksErr = await addTracksRes.text();
|
||||||
|
console.log("[SpotifyPlaylistDebug] add tracks response body if failed:", addTracksErr);
|
||||||
if (addTracksRes.status === 403 || addTracksErr.toLowerCase().includes('active premium subscription required')) {
|
if (addTracksRes.status === 403 || addTracksErr.toLowerCase().includes('active premium subscription required')) {
|
||||||
spotifyPremiumRequired = true;
|
spotifyPremiumRequired = true;
|
||||||
console.warn("Spotify add tracks skipped due to expected Premium limitation:", addTracksRes.status, addTracksErr);
|
console.warn("Spotify add tracks skipped due to expected Premium limitation:", addTracksRes.status, addTracksErr);
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ const getGooglePlacesImage = async (normalizedDestination: string, debugContext?
|
|||||||
destination: normalizedDestination,
|
destination: normalizedDestination,
|
||||||
apiKeyExists: Boolean(GOOGLE_MAPS_API_KEY),
|
apiKeyExists: Boolean(GOOGLE_MAPS_API_KEY),
|
||||||
});
|
});
|
||||||
|
console.log("[GooglePlacesDebug] EXPO_PUBLIC_GOOGLE_MAPS_API_KEY loaded exists:", Boolean(GOOGLE_MAPS_API_KEY));
|
||||||
|
|
||||||
if (!GOOGLE_MAPS_API_KEY) {
|
if (!GOOGLE_MAPS_API_KEY) {
|
||||||
console.warn('[DestinationImage] Google Places skipped: missing API key');
|
console.warn('[DestinationImage] Google Places skipped: missing API key');
|
||||||
@@ -121,6 +122,9 @@ const getGooglePlacesImage = async (normalizedDestination: string, debugContext?
|
|||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
const data = (await response.json()) as PlacesSearchResponse;
|
const data = (await response.json()) as PlacesSearchResponse;
|
||||||
|
|
||||||
|
console.log("[GooglePlacesDebug] Google API Status:", data.status);
|
||||||
|
console.log("[GooglePlacesDebug] Google API Error Message:", data.error_message || "none");
|
||||||
|
|
||||||
console.log('[DestinationImage] Google Places result:', {
|
console.log('[DestinationImage] Google Places result:', {
|
||||||
tripTitle: debugContext?.tripTitle || null,
|
tripTitle: debugContext?.tripTitle || null,
|
||||||
destination: normalizedDestination,
|
destination: normalizedDestination,
|
||||||
@@ -190,6 +194,7 @@ const getWikimediaImage = async (normalizedDestination: string, debugContext?: D
|
|||||||
const languageHosts = ['pt.wikipedia.org', 'en.wikipedia.org'];
|
const languageHosts = ['pt.wikipedia.org', 'en.wikipedia.org'];
|
||||||
|
|
||||||
for (const host of languageHosts) {
|
for (const host of languageHosts) {
|
||||||
|
try {
|
||||||
const searchUrl = `https://${host}/w/api.php?action=query&list=search&srsearch=${encodeURIComponent(normalizedDestination)}&format=json&origin=*&srlimit=1`;
|
const searchUrl = `https://${host}/w/api.php?action=query&list=search&srsearch=${encodeURIComponent(normalizedDestination)}&format=json&origin=*&srlimit=1`;
|
||||||
console.log('[DestinationImage] Wikimedia search:', {
|
console.log('[DestinationImage] Wikimedia search:', {
|
||||||
tripTitle: debugContext?.tripTitle || null,
|
tripTitle: debugContext?.tripTitle || null,
|
||||||
@@ -199,6 +204,18 @@ const getWikimediaImage = async (normalizedDestination: string, debugContext?: D
|
|||||||
});
|
});
|
||||||
|
|
||||||
const searchResponse = await fetch(searchUrl);
|
const searchResponse = await fetch(searchUrl);
|
||||||
|
if (!searchResponse.ok) {
|
||||||
|
console.warn(`[DestinationImage] Wikimedia search request failed for host ${host} with status:`, searchResponse.status);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchContentType = searchResponse.headers.get("content-type") || "";
|
||||||
|
if (!searchContentType.includes("application/json")) {
|
||||||
|
const text = await searchResponse.text();
|
||||||
|
console.warn(`[DestinationImage] Wikimedia search returned non-JSON for host ${host}:`, text.substring(0, 100));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const searchData = (await searchResponse.json()) as WikimediaSearchResponse;
|
const searchData = (await searchResponse.json()) as WikimediaSearchResponse;
|
||||||
const title = searchData.query?.search?.[0]?.title;
|
const title = searchData.query?.search?.[0]?.title;
|
||||||
|
|
||||||
@@ -208,15 +225,37 @@ const getWikimediaImage = async (normalizedDestination: string, debugContext?: D
|
|||||||
host,
|
host,
|
||||||
httpStatus: searchResponse.status,
|
httpStatus: searchResponse.status,
|
||||||
title: title || null,
|
title: title || null,
|
||||||
body: searchData,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!searchResponse.ok || !title) {
|
if (!title) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const summaryUrl = `https://${host}/api/rest_v1/page/summary/${encodeURIComponent(title)}`;
|
// Wikipedia REST API requires spaces to be replaced by underscores in titles
|
||||||
|
const formattedTitle = title.replace(/ /g, '_');
|
||||||
|
const summaryUrl = `https://${host}/api/rest_v1/page/summary/${encodeURIComponent(formattedTitle)}`;
|
||||||
|
|
||||||
|
console.log('[DestinationImage] Wikimedia summary search:', {
|
||||||
|
tripTitle: debugContext?.tripTitle || null,
|
||||||
|
destination: normalizedDestination,
|
||||||
|
host,
|
||||||
|
title,
|
||||||
|
url: summaryUrl,
|
||||||
|
});
|
||||||
|
|
||||||
const summaryResponse = await fetch(summaryUrl);
|
const summaryResponse = await fetch(summaryUrl);
|
||||||
|
if (!summaryResponse.ok) {
|
||||||
|
console.warn(`[DestinationImage] Wikimedia summary request failed for ${title} with status:`, summaryResponse.status);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const summaryContentType = summaryResponse.headers.get("content-type") || "";
|
||||||
|
if (!summaryContentType.includes("application/json")) {
|
||||||
|
const text = await summaryResponse.text();
|
||||||
|
console.warn(`[DestinationImage] Wikimedia summary returned non-JSON for ${title}:`, text.substring(0, 100));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const summaryData = (await summaryResponse.json()) as WikimediaPageSummary;
|
const summaryData = (await summaryResponse.json()) as WikimediaPageSummary;
|
||||||
const imageUrl = summaryData.originalimage?.source || summaryData.thumbnail?.source || null;
|
const imageUrl = summaryData.originalimage?.source || summaryData.thumbnail?.source || null;
|
||||||
|
|
||||||
@@ -230,7 +269,7 @@ const getWikimediaImage = async (normalizedDestination: string, debugContext?: D
|
|||||||
fallbackReason: imageUrl ? null : 'wikimedia_page_without_image',
|
fallbackReason: imageUrl ? null : 'wikimedia_page_without_image',
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!summaryResponse.ok || !imageUrl?.startsWith('https://')) {
|
if (!imageUrl || !imageUrl.startsWith('https://')) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,6 +280,9 @@ const getWikimediaImage = async (normalizedDestination: string, debugContext?: D
|
|||||||
source: 'wikimedia',
|
source: 'wikimedia',
|
||||||
fallbackReason: null,
|
fallbackReason: null,
|
||||||
};
|
};
|
||||||
|
} catch (e: any) {
|
||||||
|
console.warn(`[DestinationImage] Exception encountered in Wikimedia query flow for host ${host}:`, e.message || e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user