arnel8888's picture
Uploaded project files
c097be1 verified
Raw
History Blame Contribute Delete
6.97 kB
"""
Utility functions for the Pasig Full Disclosure API.
This module provides functions for fetching, caching, and managing HTML data
from the Pasig City government website. All timestamps use UTC+8 (Philippine Time).
"""
import requests
import os
from datetime import datetime, timezone, timedelta
from typing import Optional, Dict
# Mapping of data paths to their corresponding URLs on the Pasig City website
path_to_url: Dict[str, str] = {
"resolutions": "https://pasigcity.gov.ph/city-resolutions",
"ordinances": "https://pasigcity.gov.ph/city-ordinances",
"executive-orders": "https://pasigcity.gov.ph/executive-orders",
"bids-and-awards": "https://pasigcity.gov.ph/bids-and-awards"
}
def refresh_html(path: str) -> None:
"""
Fetch HTML content from the Pasig City website and save it to a local file.
Args:
path: The data path (e.g., 'resolutions', 'ordinances', 'executive-orders', 'bids-and-awards').
Must be a key in the path_to_url dictionary.
Returns:
None
Side Effects:
- Creates the 'data' directory if it doesn't exist
- Creates or overwrites the file 'data/{path}.html' with fetched content
"""
url = path_to_url[path]
html = requests.get(url)
# Create data folder if it doesn't exist
os.makedirs("data", exist_ok = True)
# Write the HTML content to file (creates new or replaces existing)
filename = os.path.join("data", f"{path}.html")
with open(filename, "w", encoding = "utf-8") as f:
f.write(html.text)
def update_time(path: str) -> None:
"""
Update the last refresh timestamp for a specific data path in UTC+8.
This function reads the existing timestamps from 'data/last_updated.txt', updates
the timestamp for the specified path with the current time, and writes all
timestamps back to the file. Creates the file and directory if they don't exist.
Args:
path: The data path to update (e.g., 'resolutions', 'ordinances').
Returns:
None
Side Effects:
- Creates the 'data' directory if it doesn't exist
- Creates or updates 'data/last_updated.txt' with the current timestamp
- Preserves timestamps for other paths in the file
"""
# Ensure data directory exists
os.makedirs("data", exist_ok = True)
# Use UTC+8 timezone (Philippine Time)
utc_plus_8 = timezone(timedelta(hours = 8))
current_time = datetime.now(utc_plus_8).isoformat()
# Read existing times
times = {}
last_updated_file = "data/last_updated.txt"
if os.path.exists(last_updated_file):
with open(last_updated_file, "r", encoding = "utf-8") as f:
for line in f:
line = line.strip()
if line and ":" in line:
key, value = line.split(":", 1)
times[key.strip()] = value.strip()
# Update the time for the given path
times[path] = current_time
# Write all times back to file (creates file if it doesn't exist)
with open(last_updated_file, "w", encoding = "utf-8") as f:
for key, value in times.items():
f.write(f"{key}: {value}\n")
def get_time(path: str) -> Optional[str]:
"""
Retrieve the last refresh timestamp for a specific data path.
Args:
path: The data path to look up (e.g., 'resolutions', 'ordinances').
Returns:
The ISO-format timestamp string in UTC+8 if found, None otherwise.
Returns None if the file doesn't exist or the path is not found.
Example:
>>> get_time("resolutions")
'2025-11-05T17:29:40.443171+08:00'
"""
last_updated_file = "data/last_updated.txt"
# Return None if file doesn't exist (app can rebuild from scratch)
if not os.path.exists(last_updated_file):
return None
# Read the file and search for the path
try:
with open(last_updated_file, "r", encoding = "utf-8") as f:
for line in f:
line = line.strip()
if line and ":" in line:
key, value = line.split(":", 1)
if key.strip() == path:
return value.strip()
except (IOError, OSError):
# Handle any file reading errors gracefully
return None
return None
def update_if_needed(path: str, refresh_timer: timedelta = timedelta(days = 1)) -> None:
"""
Refresh HTML content if the cached version is outdated.
This function checks the last update timestamp for the specified path and
refreshes the HTML content if the time elapsed since the last update is
greater than or equal to the refresh_timer. If no timestamp exists, it
refreshes immediately.
Args:
path: The data path to check and potentially refresh.
refresh_timer: The minimum time between refreshes (default: 1 day).
Returns:
None
Side Effects:
- May fetch new HTML content and update the local cache
- May update the timestamp in 'data/last_updated.txt'
- Creates the 'data' directory if it doesn't exist
Example:
>>> # Refresh if older than 1 day (default)
>>> update_if_needed("resolutions")
>>>
>>> # Refresh if older than 12 hours
>>> update_if_needed("ordinances", refresh_timer = timedelta(hours = 12))
"""
# Ensure data directory exists (app can rebuild from scratch)
os.makedirs("data", exist_ok = True)
# Get the last updated time for the path
last_updated_str = get_time(path)
# If no record exists, refresh immediately
if last_updated_str is None:
refresh_html(path)
update_time(path)
return
# Parse the last updated time
last_updated = datetime.fromisoformat(last_updated_str)
# Get current time in UTC+8
utc_plus_8 = timezone(timedelta(hours = 8))
current_time = datetime.now(utc_plus_8)
# Check if refresh is needed
time_difference = current_time - last_updated
if time_difference >= refresh_timer:
refresh_html(path)
update_time(path)
return
def get_current_year() -> int:
"""
Get the current year in UTC+8 (Philippine Time).
This ensures the year is always calculated based on Philippine Time,
regardless of the server's local timezone.
Returns:
The current year as an integer.
Example:
>>> get_current_year()
2025
"""
# Use UTC+8 timezone (Philippine Time)
utc_plus_8 = timezone(timedelta(hours = 8))
current_time = datetime.now(utc_plus_8)
return current_time.year