from __future__ import annotations from abc import abstractmethod from enum import Enum from dataclasses import dataclass from datetime import datetime from typing import override import psycopg2 from psycopg2 import sql class RampStatus(Enum): OPEN = "OPEN" CLOSED = "CLOSED" UNKNOWN = "UNKNOWN" @override def __str__(self): status_str = "Unknown" match self: case RampStatus.OPEN: status_str = "Open" case RampStatus.CLOSED: status_str = "Closed" case RampStatus.UNKNOWN: status_str = "Unknown" return status_str class RampOperator(Enum): CANYON_MARINA = "Canyon Lake Marina" COMAL_COUNTY = "Comal County" USACE = "US Army Corps of Engineers" CRANES_MILL = "Cranes Mill Marina" JBSA = "Joint Base San Antonio" LCYC = "Lake Canyon Yacht Club" WORD = "Water-Oriented Recreation District of Comal County" class RampOperatingTimes(Enum): CANYON_MARINA = "8am - Sunset" COMAL_COUNTY = "8am - Sunset" USACE = "8am - Sunset" CRANES_MILL = None JBSA = "8am - Sunset" LCYC = "24/7" WORD = "8am - 7:30PM" @dataclass class Ramp: """A represenation of a single boat ramp at Canyon Lake Attributes: ramp_number: the ramp number according to the US Army Corps of Engineers address: the approximate address of the ramp location: the location name of the ramp operator: the organization that runs/operates the ramp status: the ramp's current open status """ ramp_number: int name: str address: str operator: RampOperator status: RampStatus last_updated: datetime operating_times: RampOperatingTimes | None @abstractmethod def fetch_data(self): pass def save_to_db(self, conn: psycopg2.extensions.connection): with conn.cursor() as cur: cur.execute( sql.SQL( """ INSERT INTO {} VALUES (%s, %s, %s, %s, %s, %s, %s) ON CONFLICT (number) DO UPDATE SET number = EXCLUDED.number, name = EXCLUDED.name, operator = EXCLUDED.operator, address = EXCLUDED.address, status = EXCLUDED.status, last_updated = EXCLUDED.last_updated, operating_times = EXCLUDED.operating_times """ ).format(sql.Identifier("""rampdata""")), [ self.ramp_number, self.name, self.operator.value, self.address, str(self.status), self.last_updated.strftime("%Y-%m-%d"), self.operating_times.value if self.operating_times else None, ], ) conn.commit()