cocorahs
This commit is contained in:
137
covid.py
137
covid.py
@@ -11,6 +11,25 @@ import datetime
|
|||||||
from html import escape
|
from html import escape
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
|
|
||||||
|
def clean_text(text):
|
||||||
|
"""Clean text by removing problematic characters that cause encoding issues."""
|
||||||
|
if text is None:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
# Convert to string if not already
|
||||||
|
text = str(text)
|
||||||
|
|
||||||
|
# Remove the problematic 'Â' character that appears with degree symbols
|
||||||
|
text = text.replace('\u00a0', ' ') # Non-breaking space to regular space
|
||||||
|
text = text.replace('\xc2', '') # Remove standalone  character
|
||||||
|
text = text.replace('°', '°') # Fix degree symbol encoding issue
|
||||||
|
text = text.replace('°F', '°F') # Fix degree F encoding issue
|
||||||
|
text = text.replace('°C', '°C') # Fix degree C encoding issue
|
||||||
|
text = text.replace('\u00a0', ' ') # Remove non-breaking spaces
|
||||||
|
text = text.encode('utf-8', errors='ignore').decode('utf-8') # Handle other encoding issues
|
||||||
|
|
||||||
|
return text
|
||||||
|
|
||||||
allobs = []
|
allobs = []
|
||||||
|
|
||||||
states = ['wv', 'oh', 'va', 'ky']
|
states = ['wv', 'oh', 'va', 'ky']
|
||||||
@@ -55,13 +74,13 @@ try:
|
|||||||
finalobs = []
|
finalobs = []
|
||||||
for obs in allobs:
|
for obs in allobs:
|
||||||
tempob = [
|
tempob = [
|
||||||
obs.get('DateTimeStamp', ''),
|
clean_text(obs.get('DateTimeStamp', '')),
|
||||||
obs.get('StationNumber', ''),
|
clean_text(obs.get('StationNumber', '')),
|
||||||
obs.get('StationName', ''),
|
clean_text(obs.get('StationName', '')),
|
||||||
obs.get('TotalPrecipAmt', ''),
|
clean_text(obs.get('TotalPrecipAmt', '')),
|
||||||
obs.get('NewSnowDepth', ''),
|
clean_text(obs.get('NewSnowDepth', '')),
|
||||||
obs.get('TotalSnowDepth', ''),
|
clean_text(obs.get('TotalSnowDepth', '')),
|
||||||
obs.get('Notes', '')
|
clean_text(obs.get('Notes', ''))
|
||||||
]
|
]
|
||||||
finalobs.append(tempob)
|
finalobs.append(tempob)
|
||||||
|
|
||||||
@@ -78,27 +97,30 @@ try:
|
|||||||
html_content = """<!DOCTYPE html>
|
html_content = """<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
<title>Cocorahs Weather Data - """ + datewanted + """</title>
|
<title>Cocorahs Weather Data - """ + datewanted + """</title>
|
||||||
<style>
|
<style>
|
||||||
body { font-family: Arial, sans-serif; margin: 20px; }
|
body { font-family: Arial, sans-serif; margin: 20px; }
|
||||||
table { border-collapse: collapse; width: 100%; }
|
table { border-collapse: collapse; width: 100%; }
|
||||||
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
||||||
th { background-color: #f2f2f2; font-weight: bold; }
|
th { background-color: #f2f2f2; font-weight: bold; cursor: pointer; }
|
||||||
|
th:hover { background-color: #e0e0e0; }
|
||||||
tr:nth-child(even) { background-color: #f9f9f9; }
|
tr:nth-child(even) { background-color: #f9f9f9; }
|
||||||
|
.sort-arrow { margin-left: 5px; font-size: 0.8em; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Cocorahs Weather Data - """ + datewanted + """</h1>
|
<h1>Cocorahs Weather Data - """ + datewanted + """</h1>
|
||||||
<table>
|
<table id="dataTable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Date/Time of Ob (Z)</th>
|
<th onclick="sortTable(0)" title="Click to sort by Date/Time">Date/Time of Ob (Z)<span class="sort-arrow"></span></th>
|
||||||
<th>Station Number</th>
|
<th onclick="sortTable(1)" title="Click to sort by Station Number">Station Number<span class="sort-arrow"></span></th>
|
||||||
<th>Station Name</th>
|
<th onclick="sortTable(2)" title="Click to sort by Station Name">Station Name<span class="sort-arrow"></span></th>
|
||||||
<th>New Precip</th>
|
<th onclick="sortTable(3)" title="Click to sort by New Precip">New Precip<span class="sort-arrow"></span></th>
|
||||||
<th>New Snow</th>
|
<th onclick="sortTable(4)" title="Click to sort by New Snow">New Snow<span class="sort-arrow"></span></th>
|
||||||
<th>Snow Depth</th>
|
<th onclick="sortTable(5)" title="Click to sort by Snow Depth">Snow Depth<span class="sort-arrow"></span></th>
|
||||||
<th>Comments</th>
|
<th onclick="sortTable(6)" title="Click to sort by Comments">Comments<span class="sort-arrow"></span></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -112,6 +134,89 @@ try:
|
|||||||
|
|
||||||
html_content += """ </tbody>
|
html_content += """ </tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let sortDirection = Array(7).fill(true); // true for ascending, false for descending for 7 columns
|
||||||
|
|
||||||
|
function sortTable(columnIndex) {
|
||||||
|
const table = document.getElementById('dataTable');
|
||||||
|
const tbody = table.querySelector('tbody');
|
||||||
|
const rows = Array.from(tbody.rows);
|
||||||
|
|
||||||
|
// Determine the data type for this column
|
||||||
|
let isNumeric = [3, 4, 5].includes(columnIndex); // New Precip, New Snow, Snow Depth are numeric
|
||||||
|
let isDateTime = columnIndex === 0; // Date/Time is special
|
||||||
|
|
||||||
|
// Toggle sort direction
|
||||||
|
sortDirection[columnIndex] = !sortDirection[columnIndex];
|
||||||
|
const direction = sortDirection[columnIndex];
|
||||||
|
|
||||||
|
rows.sort((a, b) => {
|
||||||
|
const aCell = a.cells[columnIndex].textContent.trim();
|
||||||
|
const bCell = b.cells[columnIndex].textContent.trim();
|
||||||
|
|
||||||
|
let comparison = 0;
|
||||||
|
|
||||||
|
if (isDateTime) {
|
||||||
|
// Parse date for comparison (assuming format like: MM/DD/YYYY HH:MM:SS)
|
||||||
|
const dateA = parseDateTime(aCell);
|
||||||
|
const dateB = parseDateTime(bCell);
|
||||||
|
comparison = dateA - dateB;
|
||||||
|
} else if (isNumeric) {
|
||||||
|
// Convert to numeric values for comparison
|
||||||
|
const numA = parseFloat(aCell) || 0;
|
||||||
|
const numB = parseFloat(bCell) || 0;
|
||||||
|
comparison = numA - numB;
|
||||||
|
} else {
|
||||||
|
// Text comparison for A-Z/Z-A
|
||||||
|
comparison = aCell.localeCompare(bCell, undefined, {numeric: true, sensitivity: 'base'});
|
||||||
|
}
|
||||||
|
|
||||||
|
return direction ? comparison : -comparison;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reorder the rows in the table
|
||||||
|
rows.forEach(row => tbody.appendChild(row));
|
||||||
|
|
||||||
|
// Update sort arrows
|
||||||
|
updateSortArrows(columnIndex, direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseDateTime(dateString) {
|
||||||
|
// Handle various date formats, default to string if not parseable
|
||||||
|
if (!dateString || dateString.trim() === '') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to parse date in common formats
|
||||||
|
let date = new Date(dateString);
|
||||||
|
if (isNaN(date)) {
|
||||||
|
// Try alternative parsing if the default doesn't work
|
||||||
|
const parts = dateString.replace(',', '').split(/[\s\/:]+/);
|
||||||
|
if (parts.length >= 3) {
|
||||||
|
// Assuming MM/DD/YYYY format
|
||||||
|
date = new Date(parts[2], parts[0] - 1, parts[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return date.getTime ? date.getTime() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSortArrows(columnIndex, direction) {
|
||||||
|
// Clear all arrows first
|
||||||
|
const allArrows = document.querySelectorAll('.sort-arrow');
|
||||||
|
allArrows.forEach(arrow => arrow.textContent = '');
|
||||||
|
|
||||||
|
// Set arrow for the current column
|
||||||
|
const currentArrow = document.querySelectorAll('.sort-arrow')[columnIndex];
|
||||||
|
currentArrow.textContent = direction ? ' ▲' : ' ▼';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize arrows on load
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const arrows = document.querySelectorAll('.sort-arrow');
|
||||||
|
arrows.forEach(arrow => arrow.textContent = '');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>"""
|
</html>"""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user