a terrible but somewhat functional state

This commit is contained in:
2026-01-11 17:50:32 -07:00
parent 9dbd72f4ee
commit 7b5a49979e
12 changed files with 9814 additions and 26 deletions

View File

@@ -19,15 +19,12 @@ def create_app(test_config=None):
except OSError:
pass
@app.route('/hello')
def hello():
return "'Ello, Wurld!"
from . import db
db.init_app(app)
from . import weather
app.register_blueprint(weather.bp)
app.add_url_rule('/', endpoint='index')
app.add_url_rule('/api', endpoint='api')
return app

View File

@@ -5,7 +5,6 @@ CREATE TABLE "periods" (
"id" Integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"report_id" Integer NOT NULL,
"period_number" Integer NOT NULL,
"name" Text,
"start_time" DateTime NOT NULL,
"end_time" DateTime NOT NULL,
"is_daytime" Integer NOT NULL,

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -0,0 +1 @@
Image by <a href="https://pixabay.com/users/couleur-1195798/?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=5459972">Couleur</a> from <a href="https://pixabay.com//?utm_source=link-attribution&utm_medium=referral&utm_campaign=image&utm_content=5459972">Pixabay</a>

View File

@@ -1,20 +1,97 @@
@font-face {
font-family: "Abel";
src: url(Abel-Regular.woff2) format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
#clock {
font-size: 2em;
padding-top: 1em;
text-align: center;
}
.font-abel {
font-family: "Abel", sans-serif;
.frosted {
backdrop-filter: blur(16px) saturate(180%);
-webkit-backdrop-filter: blur(16px) saturate(180%);
background-color: rgba(78, 86, 106, 0.75);
border: 1px solid rgba(255, 255, 255, 0.125);
}
.antialiased {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
.page-container {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1.4fr 0.6fr;
gap: 2em 0em;
grid-auto-flow: row;
grid-template-areas:
"currentForecast"
"hourlyReport"
"weeklyReport";
max-width: 72em;
margin: 0 auto;
padding: 1.5em 0 2.5em;
}
.min-h-screen {
min-height: 100vh;
.currentForecast {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
"forecast secondaryInfo";
grid-area: currentForecast;
}
.forecast {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: repeat(3, max-content);
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
"shortDescription"
"longDescription"
"currentTemp"
"waterConditions";
grid-area: forecast;
}
.shortDescription {
font-size: 3em;
grid-area: shortDescription;
}
.longDescription {
font-size: 1.35em;
grid-area: longDescription;
}
.currentTemp { grid-area: currentTemp; }
.currentTemp > .temperature { font-size: 6em; }
.currentTemp > .unit { font-size: 2em; }
.waterConditions { grid-area: waterConditions; }
.secondaryInfo {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr;
gap: 2em 0;
grid-auto-flow: row;
grid-template-areas:
"windContainer"
"solarClock";
grid-area: secondaryInfo;
}
.windContainer { grid-area: windContainer; }
.solarClock { grid-area: solarClock; }
.hourlyReport { grid-area: hourlyReport; }
.weeklyReport {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
". . . . . .";
grid-area: weeklyReport;
}

View File

@@ -0,0 +1,36 @@
@font-face {
font-family: "Abel";
src: url(Abel-Regular.woff2) format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
}
.font-abel { font-family: "Abel", sans-serif; }
.antialiased {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.min-h-screen { min-height: 100vh; }
.grid { display: grid; }
.grid-cols-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.grid-cols-7 { grid-template-columns: repeat(7, minmax(0, 1fr)); }
.gap-x-4 { column-gap: 0.5rem; }
.flex { display: flex; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.justify-center { justify-content: center; }
.p-4 { padding: 1rem; }
.my-6 { margin-top: 1.25rem; margin-bottom: 1.25rem; }

View File

@@ -11,18 +11,24 @@
<!-- CSS -->
<link href="{{ url_for('static', filename='reset.css') }}" rel="stylesheet" media="screen">
<link href="{{ url_for('static', filename='tailwind.css') }}" rel="stylesheet" media="screen">
<link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet" media="screen">
<!-- JS that must be executed before the document is loaded -->
</head>
<body class="font-abel antialiased">
<div id="app" class="min-h-screen">
{% for message in get_flashed_messages() %}
<div class="flash">{{ message }}</div>
{% endfor %}
<div id="app" class="min-h-screen" style="background-image: url({{ url_for('static', filename=condition_image) }}); background-size: cover; background-position: center;">
<div id="clock">0:00:00 AM</div>
{% block content %}{% endblock %}
</div>
<script>
let clock = document.getElementById('clock');
setInterval(() => {
clock.innerText = new Date().toLocaleTimeString();
}, 1000)
</script>
</body>
</html>

View File

@@ -1,7 +1,56 @@
{% extends 'base.html' %}
{% block content %}
{% for period in periods %}
<p>{{ period['start_time'] }} - {{ period['end_time'] }} | {{ period['temperature'] }}{{ period['temperature_unit'] }}</p>
{% endfor %}
<div class="page-container">
<div class="currentForecast">
<div class="forecast">
<div class="shortDescription">{{ current_conditions['short_forecast'] }}</div>
<div class="longDescription">{{ current_conditions['detailed_forecast'] }}</div>
<div class="currentTemp">
<span class="temperature">{{ current_conditions['temperature'] }}</span><span class="unit">°{{ current_conditions['temperature_unit'] }}</span>
</div>
<div class="waterConditions">{{ current_conditions['precipitation_probability'] }}% percip | {{ current_conditions['relative_humidity'] }}% humidity (relative)</div>
</div>
<div class="secondaryInfo">
<div class="windContainer frosted">
<div class="flex items-center justify-between">
<div class="flex items-center">Wind Status</div>
<div class="flex items-center">{{ current_conditions['wind_speed'] }}</div>
</div>
<div class="flex items-center justify-center">
</div>
<div class="flex items-center justify-center">
Direction: {{ current_conditions['wind_direction'] }}
</div>
</div>
<div class="solarClock frosted">
<div class="flex items-center justify-between">
<div class="flex items-center">Sunrise</div>
<div class="flex items-center">Sunset</div>
</div>
<div class="flex items-center justify-center">
</div>
<div class="flex items-center justify-between">
<div class="flex items-center">Time AM</div>
<div class="flex items-center">Time PM</div>
</div>
</div>
</div>
</div>
<div class="hourlyForecast frosted my-6">
<h3>Hourly Forecast</h3>
<div class="grid grid-cols-6 gap-x-4">
{{ current_conditions | tojson(2) }}
</div>
</div>
<div class="weeklyReport frosted">
<h3>Weekly Forecast</h3>
<div class="grid grid-cols-7 gap-x-4">
{% for period in periods %}
<div>{{ period['start_time'] }} - {{ period['end_time'] }} | {{ period['temperature'] }}{{ period['temperature_unit'] }}</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

View File

@@ -10,9 +10,40 @@ bp = Blueprint('weather', __name__)
@bp.route('/')
def index():
db = get_db()
latest_period = dict(db.execute(
'SELECT `id` FROM `reports` WHERE `type` = "hourly" ORDER BY `reported_at` DESC'
).fetchone())
current_conditions = dict(db.execute(
f"SELECT * FROM `periods` WHERE `report_id` = {latest_period['id']} LIMIT 1"
).fetchone())
# TODO: add conditions to check for day/night
condition_image = f"images/{current_conditions['short_forecast'].lower()}.jpg"
periods = db.execute(
'SELECT *'
' FROM `periods`'
' ORDER BY `id` DESC'
' LIMIT 7'
).fetchall()
return render_template('weather/index.html', periods=periods)
return render_template(
'weather/index.html',
current_conditions=current_conditions,
condition_image=condition_image,
periods=periods
)
@bp.route('/api')
def api():
db = get_db()
latest_period = dict(db.execute(
'SELECT `id` FROM `reports` WHERE `type` = "hourly" ORDER BY `reported_at` DESC'
).fetchone())
current_conditions = dict(db.execute(
f"SELECT * FROM `periods` WHERE `report_id` = {latest_period['id']} LIMIT 1"
).fetchone())
return current_conditions