import requests import logging import time import datetime from platforms.base_platform import BasePlatform from models.article import Article REQUEST_RETRY_TIME = 5 class WallapopPlatform(BasePlatform): """Wallapop marketplace platform implementation""" def __init__(self, item_monitor): super().__init__(item_monitor) self.logger = logging.getLogger(__name__) def get_platform_name(self): return "wallapop" def create_url(self): """Create Wallapop API search URL""" url = ( f"http://api.wallapop.com/api/v3/search" f"?source=search_box" f"&keywords={self._item_monitor.get_search_query()}" f"&order_by=newest" f"&language=es_ES" ) # Only include latitude and longitude if both are not 0 if self._item_monitor.get_latitude() != 0 and self._item_monitor.get_longitude() != 0: url += ( f"&latitude={self._item_monitor.get_latitude()}" f"&longitude={self._item_monitor.get_longitude()}" ) if self._item_monitor.get_min_price() != 0: url += f"&min_sale_price={self._item_monitor.get_min_price()}" if self._item_monitor.get_max_price() != 0: url += f"&max_sale_price={self._item_monitor.get_max_price()}" if self._item_monitor.get_max_distance() != 0: url += f"&distance_in_km={self._item_monitor.get_max_distance()}" if self._item_monitor.get_condition() != "all": url += f"&condition={self._item_monitor.get_condition()}" # new, as_good_as_new, good, fair, has_given_it_all return url def get_request_headers(self): """Get Wallapop-specific headers""" headers = super().get_request_headers() headers['X-DeviceOS'] = '0' return headers def fetch_articles(self): """Fetch articles from Wallapop API""" url = self.create_url() while True: try: headers = self.get_request_headers() response = requests.get(url, headers=headers) response.raise_for_status() break except requests.exceptions.RequestException as err: self.logger.error(f"Request Exception: {err}") time.sleep(REQUEST_RETRY_TIME) json_response = response.json() json_items = json_response['data']['section']['payload']['items'] articles = self.parse_response(json_items) return articles def parse_response(self, json_items): """Parse Wallapop JSON response into Article objects""" articles = [] for json_article in json_items: article = self._parse_single_article(json_article) if article: articles.append(article) return articles def _parse_single_article(self, json_data): """Parse a single Wallapop article from JSON""" try: # Extract images with proper format images = [img['urls']['medium'] for img in json_data['images'][:3]] # Convert timestamp to datetime string ts = int(json_data['modified_at']) dt = datetime.datetime.fromtimestamp(ts / 1000) modified_at = dt.strftime("%Y-%m-%d %H:%M:%S") return Article( id=json_data['id'], title=json_data['title'], description=json_data['description'], price=json_data['price']['amount'], currency=json_data['price']['currency'], location=json_data['location']['city'], allows_shipping=json_data['shipping']['user_allows_shipping'], url="https://wallapop.com/item/" + json_data['web_slug'], images=images, modified_at=modified_at, platform=self.get_platform_name() ) except (KeyError, ValueError) as e: self.logger.error(f"Error parsing Wallapop article: {e}") return None