Compare commits
1
Commits
6b16496301
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a6910c1fa |
@@ -454,7 +454,7 @@ class MobileDeClient:
|
|||||||
) or None
|
) or None
|
||||||
return MobileDeListing(
|
return MobileDeListing(
|
||||||
id=listing_id,
|
id=listing_id,
|
||||||
url=MobileDeClient.build_detail_url(listing_id) if listing_id else "",
|
url=MobileDeClient.build_transport_detail_url(listing_id) if listing_id else "",
|
||||||
title=item.get("shortTitle"),
|
title=item.get("shortTitle"),
|
||||||
subtitle=item.get("subTitle"),
|
subtitle=item.get("subTitle"),
|
||||||
price=item.get("p"),
|
price=item.get("p"),
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ class MobileDeMapper:
|
|||||||
new_car=self._bool_value(detail.get("isConditionNew")),
|
new_car=self._bool_value(detail.get("isConditionNew")),
|
||||||
is_hidden=False,
|
is_hidden=False,
|
||||||
origin="MOBILEDE",
|
origin="MOBILEDE",
|
||||||
origin_url=MobileDeClient.build_detail_url(listing_id),
|
origin_url=MobileDeClient.build_transport_detail_url(listing_id),
|
||||||
origin_id=origin_id,
|
origin_id=origin_id,
|
||||||
is_damaged=is_damaged,
|
is_damaged=is_damaged,
|
||||||
evaluation=self._rating_text(detail.get("priceRating") or detail.get("rating")),
|
evaluation=self._rating_text(detail.get("priceRating") or detail.get("rating")),
|
||||||
|
|||||||
@@ -841,7 +841,7 @@ class PersistenceService:
|
|||||||
order_by = Car.last_seen_at.desc() if newest_first else Car.last_seen_at.asc()
|
order_by = Car.last_seen_at.desc() if newest_first else Car.last_seen_at.asc()
|
||||||
with self.session_scope() as session:
|
with self.session_scope() as session:
|
||||||
result = session.execute(
|
result = session.execute(
|
||||||
select(Car.id, Car.origin_url, Car.last_seen_at).where(
|
select(Car.id, Car.origin_id, Car.last_seen_at).where(
|
||||||
_origin_prefix_filter(Car.origin_id, prefixes),
|
_origin_prefix_filter(Car.origin_id, prefixes),
|
||||||
Car.is_sold == False, # noqa: E712
|
Car.is_sold == False, # noqa: E712
|
||||||
).order_by(order_by).limit(limit)
|
).order_by(order_by).limit(limit)
|
||||||
|
|||||||
@@ -1571,12 +1571,14 @@ def _mobilede_probe_active_listing_status(
|
|||||||
client: MobileDeClient,
|
client: MobileDeClient,
|
||||||
*,
|
*,
|
||||||
car_id: int,
|
car_id: int,
|
||||||
origin_url: str,
|
origin_id: str,
|
||||||
) -> tuple[str, int | None]:
|
) -> tuple[str, int | None]:
|
||||||
url = str(origin_url or "").strip()
|
source_id = str(origin_id or "").strip()
|
||||||
if not url:
|
listing_id = source_id.rsplit(":", 1)[-1].strip()
|
||||||
logger.warning("mobile.de sold probe skipped: car_id=%s reason=missing_origin_url", car_id)
|
if not listing_id:
|
||||||
|
logger.warning("mobile.de sold probe skipped: car_id=%s reason=missing_origin_id", car_id)
|
||||||
return "skipped", None
|
return "skipped", None
|
||||||
|
url = MobileDeClient.build_transport_detail_url(listing_id)
|
||||||
try:
|
try:
|
||||||
client.fetch_html(url, timeout=30)
|
client.fetch_html(url, timeout=30)
|
||||||
return "available", 200
|
return "available", 200
|
||||||
@@ -2270,11 +2272,11 @@ def mobilede_verify_active_sold_batch_task(
|
|||||||
skipped = 0
|
skipped = 0
|
||||||
checked = 0
|
checked = 0
|
||||||
|
|
||||||
for index, (car_id, origin_url, _last_seen_at) in enumerate(active_cars):
|
for index, (car_id, origin_id, _last_seen_at) in enumerate(active_cars):
|
||||||
verdict, status_code = _mobilede_probe_active_listing_status(
|
verdict, status_code = _mobilede_probe_active_listing_status(
|
||||||
client,
|
client,
|
||||||
car_id=int(car_id),
|
car_id=int(car_id),
|
||||||
origin_url=str(origin_url or ""),
|
origin_id=str(origin_id or ""),
|
||||||
)
|
)
|
||||||
checked += 1
|
checked += 1
|
||||||
if verdict == "available":
|
if verdict == "available":
|
||||||
|
|||||||
@@ -126,6 +126,18 @@ class TestMobileDeDetailTransports(unittest.TestCase):
|
|||||||
self.assertEqual(record.year, 2022)
|
self.assertEqual(record.year, 2022)
|
||||||
self.assertEqual(record.mileage, 18285)
|
self.assertEqual(record.mileage, 18285)
|
||||||
self.assertEqual(len(record.images), 1)
|
self.assertEqual(len(record.images), 1)
|
||||||
|
self.assertEqual(
|
||||||
|
record.origin_url,
|
||||||
|
MobileDeClient.build_transport_detail_url("461936419"),
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_search_listing_uses_russian_transport_detail_url(self) -> None:
|
||||||
|
listing = MobileDeClient._map_listing({"id": "461936419"})
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
listing.url,
|
||||||
|
MobileDeClient.build_transport_detail_url("461936419"),
|
||||||
|
)
|
||||||
|
|
||||||
def test_legacy_transport_is_explicitly_opt_in(self) -> None:
|
def test_legacy_transport_is_explicitly_opt_in(self) -> None:
|
||||||
client = MobileDeClient()
|
client = MobileDeClient()
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ class TestWorkerRuntimeTaskHelpers(unittest.TestCase):
|
|||||||
redis_client = self._FakeRedis()
|
redis_client = self._FakeRedis()
|
||||||
persistence = MagicMock()
|
persistence = MagicMock()
|
||||||
persistence.get_active_cars_batch_for_sold_probe.return_value = [
|
persistence.get_active_cars_batch_for_sold_probe.return_value = [
|
||||||
(index, f"https://example.test/{index}", datetime.now(timezone.utc))
|
(index, f"mobile.de:{index}", datetime.now(timezone.utc))
|
||||||
for index in range(1, 6)
|
for index in range(1, 6)
|
||||||
]
|
]
|
||||||
client = MagicMock()
|
client = MagicMock()
|
||||||
@@ -300,9 +300,28 @@ class TestWorkerRuntimeTaskHelpers(unittest.TestCase):
|
|||||||
self.assertEqual(result["blocked"], 3)
|
self.assertEqual(result["blocked"], 3)
|
||||||
self.assertEqual(result["skipped"], 2)
|
self.assertEqual(result["skipped"], 2)
|
||||||
self.assertEqual(probe.call_count, 3)
|
self.assertEqual(probe.call_count, 3)
|
||||||
|
self.assertEqual(
|
||||||
|
[call.kwargs["origin_id"] for call in probe.call_args_list],
|
||||||
|
["mobile.de:1", "mobile.de:2", "mobile.de:3"],
|
||||||
|
)
|
||||||
persistence.mark_cars_sold_by_ids.assert_not_called()
|
persistence.mark_cars_sold_by_ids.assert_not_called()
|
||||||
self.assertIn(tasks.MOBILEDE_SOLD_PROBE_ANTIBOT_BLOCK_KEY, redis_client.store)
|
self.assertIn(tasks.MOBILEDE_SOLD_PROBE_ANTIBOT_BLOCK_KEY, redis_client.store)
|
||||||
|
|
||||||
|
def test_sold_probe_uses_russian_transport_url_from_origin_id(self) -> None:
|
||||||
|
client = MagicMock()
|
||||||
|
|
||||||
|
verdict, status_code = tasks._mobilede_probe_active_listing_status(
|
||||||
|
client,
|
||||||
|
car_id=1,
|
||||||
|
origin_id="mobile.de:461936419",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual((verdict, status_code), ("available", 200))
|
||||||
|
client.fetch_html.assert_called_once_with(
|
||||||
|
"https://www.mobile.de/ru/транспортные-средства/подробности.html?id=461936419&vc=Car&s=Car&lang=ru",
|
||||||
|
timeout=30,
|
||||||
|
)
|
||||||
|
|
||||||
def test_runtime_numeric_filters_intersect_planner_segment(self) -> None:
|
def test_runtime_numeric_filters_intersect_planner_segment(self) -> None:
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
search_sync._intersect_numeric_bounds("10000", "30000", 15000, 25000),
|
search_sync._intersect_numeric_bounds("10000", "30000", 15000, 25000),
|
||||||
|
|||||||
Reference in New Issue
Block a user