95 lines
2.5 KiB
TypeScript
95 lines
2.5 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { prisma } from '@/lib/db';
|
|
|
|
export interface SearchResult {
|
|
title: string;
|
|
description: string;
|
|
thumbnail?: string;
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
const searchParams = request.nextUrl.searchParams;
|
|
const query = searchParams.get('query');
|
|
|
|
if (!query) {
|
|
return NextResponse.json(
|
|
{ error: 'Query parameter is required' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
try {
|
|
// Use the Wikipedia Action API for search
|
|
const response = await fetch(
|
|
`https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${encodeURIComponent(query)}&srlimit=20&format=json&origin=*`,
|
|
{
|
|
headers: {
|
|
'User-Agent': 'WikiPlus/1.0',
|
|
},
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
throw new Error('Failed to fetch from Wikipedia API');
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
// Get page IDs for thumbnail fetching
|
|
const searchResults = data.query?.search || [];
|
|
const pageIds = searchResults.map((r: { pageid: number }) => r.pageid).join('|');
|
|
|
|
// Fetch thumbnails for results
|
|
let thumbnails: Record<string, string> = {};
|
|
if (pageIds) {
|
|
const thumbResponse = await fetch(
|
|
`https://en.wikipedia.org/w/api.php?action=query&pageids=${pageIds}&prop=pageimages&pithumbsize=200&format=json&origin=*`,
|
|
{
|
|
headers: {
|
|
'User-Agent': 'WikiPlus/1.0',
|
|
},
|
|
}
|
|
);
|
|
if (thumbResponse.ok) {
|
|
const thumbData = await thumbResponse.json();
|
|
const pages = thumbData.query?.pages || {};
|
|
for (const pageId in pages) {
|
|
if (pages[pageId].thumbnail) {
|
|
thumbnails[pageId] = pages[pageId].thumbnail.source;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const results: SearchResult[] = searchResults.map((item: {
|
|
pageid: number;
|
|
title: string;
|
|
snippet: string;
|
|
}) => ({
|
|
title: item.title,
|
|
description: item.snippet.replace(/<[^>]*>/g, ''), // Strip HTML tags from snippet
|
|
thumbnail: thumbnails[item.pageid.toString()],
|
|
}));
|
|
|
|
// Log the search
|
|
try {
|
|
await prisma.search.create({
|
|
data: {
|
|
query,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
console.error('Error logging search:', error);
|
|
// Don't fail the search if logging fails
|
|
}
|
|
|
|
return NextResponse.json({ results });
|
|
} catch (error) {
|
|
console.error('Error searching Wikipedia:', error);
|
|
return NextResponse.json(
|
|
{ error: 'Failed to search Wikipedia' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|