Spaces:
Sleeping
Sleeping
| """Data models for Mi Pesca RD application.""" | |
| from dataclasses import dataclass, field | |
| from datetime import datetime | |
| from typing import List, Optional, Literal | |
| class ClosedSeason: | |
| """Closed season information for a species.""" | |
| start: str # MM-DD format | |
| end: str # MM-DD format | |
| description: str | |
| class Species: | |
| """Species data model.""" | |
| id: str | |
| commonName: str | |
| scientificName: str | |
| category: Literal['Peces', 'Crustáceos', 'Moluscos', 'Fondo', 'Pelágico', 'Invertebrado'] | |
| imageUrl: str | |
| protected: bool | |
| closedSeason: Optional[ClosedSeason] = None | |
| def to_dict(self): | |
| """Convert to dictionary for JSON serialization.""" | |
| data = { | |
| 'id': self.id, | |
| 'commonName': self.commonName, | |
| 'scientificName': self.scientificName, | |
| 'category': self.category, | |
| 'imageUrl': self.imageUrl, | |
| 'protected': self.protected | |
| } | |
| if self.closedSeason: | |
| data['closedSeason'] = { | |
| 'start': self.closedSeason.start, | |
| 'end': self.closedSeason.end, | |
| 'description': self.closedSeason.description | |
| } | |
| return data | |
| class CaptureItem: | |
| """Individual capture item (species with quantity).""" | |
| speciesId: str | |
| quantity: float | |
| unit: Literal['lbs', 'units'] | |
| customName: Optional[str] = None | |
| commonName: Optional[str] = None | |
| category: Optional[str] = None | |
| def to_dict(self): | |
| """Convert to dictionary for JSON serialization.""" | |
| return { | |
| 'speciesId': self.speciesId, | |
| 'quantity': self.quantity, | |
| 'unit': self.unit, | |
| 'customName': self.customName, | |
| 'commonName': self.commonName, | |
| 'category': self.category | |
| } | |
| class Capture: | |
| """Capture data model.""" | |
| id: str | |
| timestamp: datetime | |
| latitude: float | |
| longitude: float | |
| species: List[str] | |
| items: List[CaptureItem] | |
| fishingMethod: str | |
| depth: float | |
| synced: bool | |
| # Simplified fields | |
| port: Optional[str] = None | |
| phone: Optional[str] = None | |
| userId: Optional[str] = None | |
| placeName: Optional[str] = None | |
| totalWeight: float = 0 | |
| captureSource: str = 'device-gps' | |
| syncedAt: Optional[datetime] = None | |
| temperature: Optional[float] = None | |
| seaState: Optional[str] = None | |
| def to_dict(self): | |
| """Convert to dictionary for JSON serialization.""" | |
| return { | |
| 'id': self.id, | |
| 'timestamp': self.timestamp.isoformat() if isinstance(self.timestamp, datetime) else self.timestamp, | |
| 'latitude': self.latitude, | |
| 'longitude': self.longitude, | |
| 'species': self.species, | |
| 'items': [item.to_dict() if hasattr(item, 'to_dict') else item for item in self.items], | |
| 'fishingMethod': self.fishingMethod, | |
| 'depth': self.depth, | |
| 'synced': self.synced, | |
| 'port': self.port, | |
| 'phone': self.phone, | |
| 'userId': self.userId, | |
| 'placeName': self.placeName, | |
| 'totalWeight': self.totalWeight, | |
| 'captureSource': self.captureSource, | |
| 'syncedAt': self.syncedAt.isoformat() if self.syncedAt and isinstance(self.syncedAt, datetime) else self.syncedAt, | |
| 'temperature': self.temperature, | |
| 'seaState': self.seaState | |
| } | |
| def from_dict(cls, data: dict): | |
| """Create Capture instance from dictionary.""" | |
| items = [] | |
| for item in data.get('items', []): | |
| if isinstance(item, dict): | |
| items.append(CaptureItem(**item)) | |
| else: | |
| items.append(item) | |
| timestamp = data.get('timestamp') | |
| if isinstance(timestamp, str): | |
| timestamp = datetime.fromisoformat(timestamp.replace('Z', '+00:00')) | |
| syncedAt = data.get('syncedAt') | |
| if syncedAt and isinstance(syncedAt, str): | |
| syncedAt = datetime.fromisoformat(syncedAt.replace('Z', '+00:00')) | |
| return cls( | |
| id=data.get('id'), | |
| timestamp=timestamp, | |
| latitude=data.get('latitude'), | |
| longitude=data.get('longitude'), | |
| species=data.get('species', []), | |
| items=items, | |
| fishingMethod=data.get('fishingMethod'), | |
| depth=data.get('depth'), | |
| synced=data.get('synced', False), | |
| port=data.get('port'), | |
| phone=data.get('phone'), | |
| userId=data.get('userId'), | |
| placeName=data.get('placeName'), | |
| totalWeight=data.get('totalWeight', 0), | |
| captureSource=data.get('captureSource', 'device-gps'), | |
| syncedAt=syncedAt, | |
| temperature=data.get('temperature'), | |
| seaState=data.get('seaState') | |
| ) | |