feat: parse project metadata from PF links
This commit is contained in:
@@ -189,6 +189,43 @@ def add_competitor_url(db: Session, project: Project, url: str) -> tuple[Competi
|
||||
return listing, ""
|
||||
|
||||
|
||||
def parse_our_listing_url(url: str) -> dict:
|
||||
"""Parse our own PF listing for project metadata.
|
||||
|
||||
Used by the Go API before project validation, so users can paste only the
|
||||
concrete object URL and let the service fill price/permit/building/area.
|
||||
"""
|
||||
url = (url or "").strip()
|
||||
if not url:
|
||||
raise ValueError("URL пустой")
|
||||
source = detect_source_from_url(url)
|
||||
if source is None:
|
||||
raise ValueError("URL должен быть с propertyfinder.ae или bayut.com")
|
||||
if source == Source.BAYUT and not BAYUT_ENABLED:
|
||||
raise ValueError(
|
||||
"Bayut временно не поддерживается — площадка перешла на защищённый "
|
||||
"рендеринг. Используйте ссылку PropertyFinder."
|
||||
)
|
||||
if not _is_supported_listing_url(source, url):
|
||||
raise ValueError("Укажите ссылку на конкретное объявление, а не на страницу поиска")
|
||||
|
||||
scraped = _scraper_for(source).fetch_listing(url)
|
||||
if scraped is None:
|
||||
raise ValueError("Не удалось загрузить страницу — сайт мог заблокировать запрос, попробуйте позже")
|
||||
if not scraped.is_active:
|
||||
raise ValueError("Страница объявления вернула 404 — ссылка битая или объявление снято")
|
||||
|
||||
return {
|
||||
"title": scraped.title,
|
||||
"our_price": scraped.price,
|
||||
"dld_permit": scraped.permit_number,
|
||||
"building": scraped.building,
|
||||
"bedrooms": scraped.bedrooms,
|
||||
"size_sqft": scraped.size_sqft,
|
||||
"currency": scraped.currency or "AED",
|
||||
}
|
||||
|
||||
|
||||
def add_competitor_urls(db: Session, project: Project, urls: list[str]) -> dict:
|
||||
"""Add several pasted/selected URLs in one go (used by the suggest page's
|
||||
multi-select). Processes them sequentially — each one re-fetches the page —
|
||||
@@ -421,6 +458,12 @@ def refresh_our_listing(db: Session, project: Project, *, now: datetime | None =
|
||||
changed: list[str] = []
|
||||
if scraped.permit_number and not project.dld_permit:
|
||||
project.dld_permit = scraped.permit_number
|
||||
if scraped.building and not project.building:
|
||||
project.building = scraped.building
|
||||
if scraped.bedrooms is not None and project.bedrooms is None:
|
||||
project.bedrooms = scraped.bedrooms
|
||||
if scraped.size_sqft is not None and project.size_sqft is None:
|
||||
project.size_sqft = scraped.size_sqft
|
||||
|
||||
old_price = project.our_price
|
||||
new_price = scraped.price
|
||||
|
||||
Reference in New Issue
Block a user