refactoring
This commit is contained in:
151
web/js/api.js
Normal file
151
web/js/api.js
Normal file
@ -0,0 +1,151 @@
|
||||
// API communication functions
|
||||
|
||||
async function scrapeNextListing() {
|
||||
if (!AppState.currentSessionId || !AppState.isScrapingActive) {
|
||||
console.log('Scraping stopped: session or active flag cleared');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/api/scrape/${AppState.currentSessionId}`);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.cancelled) {
|
||||
console.log('Scraping cancelled by backend');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data.listing) {
|
||||
AppState.allListings.push(data.listing);
|
||||
addMarker(data.listing);
|
||||
|
||||
// Update display
|
||||
const sortBy = document.getElementById('sortSelect').value;
|
||||
const sortedListings = sortListings(AppState.allListings, sortBy);
|
||||
renderResults(sortedListings);
|
||||
|
||||
// Fit map to markers
|
||||
if (AppState.markers.length > 0) {
|
||||
const group = L.featureGroup(AppState.markers);
|
||||
AppState.map.fitBounds(group.getBounds().pad(0.1));
|
||||
}
|
||||
}
|
||||
|
||||
updateProgress(data.progress.current, data.progress.total);
|
||||
|
||||
if (data.complete) {
|
||||
console.log('Scraping complete, finalizing...');
|
||||
AppState.isScrapingActive = false;
|
||||
document.getElementById('searchBtn').disabled = false;
|
||||
document.getElementById('cancelBtn').style.display = 'none';
|
||||
updateProgress(0, 0);
|
||||
showStatus(`Fertig! ${AppState.allListings.length} Inserate geladen`, 'success');
|
||||
console.log('Final listings count:', AppState.allListings.length);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Scrape error:', error);
|
||||
AppState.isScrapingActive = false;
|
||||
document.getElementById('searchBtn').disabled = false;
|
||||
document.getElementById('cancelBtn').style.display = 'none';
|
||||
showStatus('Fehler beim Laden der Inserate', 'error');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function startScrapingLoop() {
|
||||
while (AppState.isScrapingActive && AppState.currentSessionId) {
|
||||
const shouldContinue = await scrapeNextListing();
|
||||
if (!shouldContinue) {
|
||||
break;
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
}
|
||||
|
||||
async function searchListings() {
|
||||
const searchTerm = document.getElementById('searchTerm').value.trim();
|
||||
const minPrice = parseInt(document.getElementById('minPrice').value) || 0;
|
||||
const maxPriceInput = document.getElementById('maxPrice').value;
|
||||
const maxPrice = maxPriceInput ? parseInt(maxPriceInput) : 1000000000;
|
||||
const numListings = parseInt(document.getElementById('numListings').value) || 25;
|
||||
|
||||
if (!searchTerm) {
|
||||
showStatus('Bitte Suchbegriff eingeben', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById('searchBtn').disabled = true;
|
||||
clearMarkers();
|
||||
AppState.allListings = [];
|
||||
AppState.selectedListingId = null;
|
||||
document.getElementById('resultsList').innerHTML = '';
|
||||
|
||||
showStatus('Suche nach Inseraten...', 'loading');
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/api/search`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
search_term: searchTerm,
|
||||
min_price: minPrice,
|
||||
max_price: maxPrice,
|
||||
num_listings: numListings
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('API request failed');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
AppState.currentSessionId = data.session_id;
|
||||
|
||||
if (data.total === 0) {
|
||||
showStatus('Keine Inserate gefunden', 'error');
|
||||
document.getElementById('searchBtn').disabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
showStatus(`${data.total} Inserate gefunden. Lade Details...`, 'success');
|
||||
|
||||
// Show cancel button
|
||||
document.getElementById('cancelBtn').style.display = 'inline-block';
|
||||
|
||||
// Start scraping
|
||||
AppState.isScrapingActive = true;
|
||||
AppState.scrapeStartTime = Date.now();
|
||||
updateProgress(0, data.total);
|
||||
startScrapingLoop();
|
||||
|
||||
} catch (error) {
|
||||
console.error('Search error:', error);
|
||||
showStatus('Fehler: Verbindung zum Server fehlgeschlagen', 'error');
|
||||
document.getElementById('searchBtn').disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function cancelScraping() {
|
||||
if (!AppState.currentSessionId) return;
|
||||
|
||||
try {
|
||||
await fetch(`${API_BASE_URL}/api/scrape/${AppState.currentSessionId}/cancel`, {
|
||||
method: 'POST'
|
||||
});
|
||||
|
||||
AppState.isScrapingActive = false;
|
||||
document.getElementById('searchBtn').disabled = false;
|
||||
document.getElementById('cancelBtn').style.display = 'none';
|
||||
updateProgress(0, 0);
|
||||
showStatus(`Abgebrochen. ${AppState.allListings.length} Inserate geladen`, 'error');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Cancel error:', error);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user