-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodels.py
More file actions
83 lines (66 loc) · 2.33 KB
/
models.py
File metadata and controls
83 lines (66 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
"""
Data models for Finn.no scraper.
"""
import csv
import json
from dataclasses import dataclass, field, asdict
from datetime import datetime
from typing import List, Optional
@dataclass
class CarListing:
"""Represents a single car listing from Finn.no."""
title: str
price: str
year: str
mileage: str
fuel_type: str
transmission: str
location: str
seller_name: str
seller_type: str # "Forhandler" (Dealer) or "Privat" (Private)
listing_id: str
listing_url: str
image_url: str = ""
time_posted: str = ""
scraped_at: str = field(default_factory=lambda: datetime.now().isoformat())
def to_dict(self) -> dict:
"""Convert listing to dictionary."""
return asdict(self)
class ListingCollection:
"""Collection of car listings with export capabilities."""
def __init__(self):
self.listings: List[CarListing] = []
self._seen_ids: set = set()
def add(self, listing: CarListing) -> bool:
"""Add a listing to the collection. Returns True if added, False if duplicate."""
if listing.listing_id in self._seen_ids:
return False
self._seen_ids.add(listing.listing_id)
self.listings.append(listing)
return True
def add_many(self, listings: List[CarListing]) -> int:
"""Add multiple listings. Returns count of newly added listings."""
added = 0
for listing in listings:
if self.add(listing):
added += 1
return added
def __len__(self) -> int:
return len(self.listings)
def __iter__(self):
return iter(self.listings)
def to_csv(self, filepath: str) -> None:
"""Export listings to CSV file."""
if not self.listings:
return
fieldnames = list(asdict(self.listings[0]).keys())
with open(filepath, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for listing in self.listings:
writer.writerow(listing.to_dict())
def to_json(self, filepath: str) -> None:
"""Export listings to JSON file."""
data = [listing.to_dict() for listing in self.listings]
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=2, ensure_ascii=False)