Update
This commit is contained in:
parent
df22d46260
commit
438920ece6
5 changed files with 217 additions and 240 deletions
|
@ -48,9 +48,9 @@ pub mod keys {
|
||||||
#[serde(rename = "t")]
|
#[serde(rename = "t")]
|
||||||
pub teachers: Option<Vec<String>>,
|
pub teachers: Option<Vec<String>>,
|
||||||
#[serde(rename = "pr")]
|
#[serde(rename = "pr")]
|
||||||
pub prev_room: Option<String>,
|
pub prev_rooms: Vec<String>,
|
||||||
#[serde(rename = "r")]
|
#[serde(rename = "r")]
|
||||||
pub room: Option<String>,
|
pub rooms: Vec<String>,
|
||||||
#[serde(rename = "tx")]
|
#[serde(rename = "tx")]
|
||||||
pub text: Option<String>,
|
pub text: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use std::vec;
|
||||||
|
|
||||||
use crate::cache;
|
use crate::cache;
|
||||||
use crate::config;
|
use crate::config;
|
||||||
|
@ -84,7 +85,7 @@ async fn fetch_substitutions(
|
||||||
schoolyear_id,
|
schoolyear_id,
|
||||||
date,
|
date,
|
||||||
week_type,
|
week_type,
|
||||||
queried_at: Utc::now().naive_utc(),
|
queried_at: Local::now().naive_local(),
|
||||||
})
|
})
|
||||||
.returning(db::schema::substitution_queries::id)
|
.returning(db::schema::substitution_queries::id)
|
||||||
.get_result::<i64>(db_conn)?;
|
.get_result::<i64>(db_conn)?;
|
||||||
|
@ -315,41 +316,33 @@ fn cache_substitutions(
|
||||||
.order(db::schema::substitution_teachers::position.asc())
|
.order(db::schema::substitution_teachers::position.asc())
|
||||||
.load::<db::models::SubstitutionTeacher>(db_conn)?;
|
.load::<db::models::SubstitutionTeacher>(db_conn)?;
|
||||||
|
|
||||||
let (prev_room, room) = if let Some(r) = db::schema::substitution_rooms::table
|
let (prev_rooms, rooms) = {
|
||||||
.filter(db::schema::substitution_rooms::substitution_id.eq(s.id))
|
let r: Vec<db::models::SubstitutionRoom> =
|
||||||
.order(db::schema::substitution_rooms::position.asc())
|
db::schema::substitution_rooms::table
|
||||||
.first::<db::models::SubstitutionRoom>(db_conn)
|
.filter(db::schema::substitution_rooms::substitution_id.eq(s.id))
|
||||||
.optional()?
|
.order(db::schema::substitution_rooms::position.asc())
|
||||||
{
|
.load::<db::models::SubstitutionRoom>(db_conn)?;
|
||||||
let name = if let Some(id) = r.room_id {
|
|
||||||
Some(
|
let prev_rooms = db::schema::rooms::table
|
||||||
db::schema::rooms::table
|
.select(db::schema::rooms::name)
|
||||||
.select(db::schema::rooms::name)
|
.filter(
|
||||||
.filter(db::schema::rooms::id.eq(id))
|
db::schema::rooms::id
|
||||||
.first::<String>(db_conn)?,
|
.eq_any(r.iter().flat_map(|x| x.original_id).collect::<Vec<i32>>()),
|
||||||
)
|
)
|
||||||
} else {
|
.load::<String>(db_conn)?;
|
||||||
None
|
|
||||||
};
|
let rooms = db::schema::rooms::table
|
||||||
|
.select(db::schema::rooms::name)
|
||||||
|
.filter(
|
||||||
|
db::schema::rooms::id
|
||||||
|
.eq_any(r.iter().flat_map(|x| x.room_id).collect::<Vec<i32>>()),
|
||||||
|
)
|
||||||
|
.load::<String>(db_conn)?;
|
||||||
|
|
||||||
match s.subst_type {
|
match s.subst_type {
|
||||||
db::models::SubstitutionType::Cancel => (name, None),
|
db::models::SubstitutionType::Cancel => (rooms, vec![]),
|
||||||
_ => (
|
_ => (prev_rooms, rooms),
|
||||||
if let Some(id) = r.original_id {
|
|
||||||
Some(
|
|
||||||
db::schema::rooms::table
|
|
||||||
.select(db::schema::rooms::name)
|
|
||||||
.filter(db::schema::rooms::id.eq(id))
|
|
||||||
.first::<String>(db_conn)?,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
name,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
(None, None)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let (prev_subject, subject) = {
|
let (prev_subject, subject) = {
|
||||||
|
@ -406,9 +399,15 @@ fn cache_substitutions(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
prev_room,
|
prev_rooms,
|
||||||
room,
|
rooms,
|
||||||
text: s.text,
|
text: if s.text.is_none()
|
||||||
|
&& s.subst_type == db::models::SubstitutionType::RoomChange
|
||||||
|
{
|
||||||
|
Some("Raumänderung".to_string())
|
||||||
|
} else {
|
||||||
|
s.text
|
||||||
|
},
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
|
37
bvplan/templates/base.html
Normal file
37
bvplan/templates/base.html
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de-DE">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta name="generator" content="BVplan" />
|
||||||
|
<title>{% block title %}{% endblock %} | dergrimm.net</title>
|
||||||
|
|
||||||
|
<link rel="shortcut icon" href="/static/favicon.ico" />
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||||
|
<link rel="manifest" href="/static/site.webmanifest">
|
||||||
|
|
||||||
|
{% block head %}{% endblock %}
|
||||||
|
|
||||||
|
<!-- Matomo -->
|
||||||
|
<script>
|
||||||
|
var _paq = window._paq = window._paq || [];
|
||||||
|
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
||||||
|
_paq.push(['trackPageView']);
|
||||||
|
_paq.push(['enableLinkTracking']);
|
||||||
|
(function() {
|
||||||
|
var u="//matomo.dergrimm.net/";
|
||||||
|
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||||
|
_paq.push(['setSiteId', '6']);
|
||||||
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||||
|
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<!-- End Matomo Code -->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% block body %}{% endblock %}
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,171 +1,143 @@
|
||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="de-DE">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<meta name="generator" content="BVplan" />
|
|
||||||
<title>BVplan | dergrimm.net</title>
|
|
||||||
|
|
||||||
<link rel="shortcut icon" href="/static/favicon.ico" />
|
{% block title %}BVplan{% endblock %}
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
|
||||||
<link rel="manifest" href="/static/site.webmanifest">
|
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="/static/css/bvplan.css" />
|
{% block head %}
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/css/bvplan.css" />
|
||||||
|
|
||||||
<script id="data-element-count" type="application/json">{{ data.substitutions.len()|json|safe }}</script>
|
<script id="data-element-count" type="application/json">{{ data.substitutions.len()|json|safe }}</script>
|
||||||
|
|
||||||
<script
|
<script
|
||||||
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"
|
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"
|
||||||
integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ=="
|
integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ=="
|
||||||
crossorigin="anonymous"
|
crossorigin="anonymous"
|
||||||
referrerpolicy="no-referrer"
|
referrerpolicy="no-referrer"
|
||||||
></script>
|
></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
<!-- Matomo -->
|
{% block body %}
|
||||||
<script>
|
<header id="info">
|
||||||
var _paq = window._paq = window._paq || [];
|
<div id="title-wrapper" class="column">
|
||||||
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
<h1 id="title">BVplan</h1>
|
||||||
_paq.push(['trackPageView']);
|
<span id="subtitle">dergrimm.net</span>
|
||||||
_paq.push(['enableLinkTracking']);
|
</div>
|
||||||
(function() {
|
<div id="tenant-info" class="column">
|
||||||
var u="//matomo.dergrimm.net/";
|
<span>{{ data.tenant }}, {{ data.schoolyear }}</span>
|
||||||
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
<br />
|
||||||
_paq.push(['setSiteId', '6']);
|
<span>Stand: {{ data.queried_at }}</span>
|
||||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
<br />
|
||||||
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
<span>Vertretungsplan (offline): {{ data.last_import_time }}</span>
|
||||||
})();
|
</div>
|
||||||
</script>
|
</header>
|
||||||
<!-- End Matomo Code -->
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<header id="info">
|
|
||||||
<div id="title-wrapper" class="column">
|
|
||||||
<h1 id="title">BVplan</h1>
|
|
||||||
<span id="subtitle">dergrimm.net</span>
|
|
||||||
</div>
|
|
||||||
<div id="tenant-info" class="column">
|
|
||||||
<span>{{ data.tenant }}, {{ data.schoolyear }}</span>
|
|
||||||
<br />
|
|
||||||
<span>Stand: {{ data.queried_at }}</span>
|
|
||||||
<br />
|
|
||||||
<span>Untis: {{ data.last_import_time }}</span>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<table id="plan">
|
<table id="plan">
|
||||||
<caption>
|
<caption>
|
||||||
{{ data.date }}, Woche {{ data.week_type }}
|
{{ data.date }}, Woche {{ data.week_type }}
|
||||||
</caption>
|
</caption>
|
||||||
|
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<col />
|
<col />
|
||||||
<col />
|
<col />
|
||||||
<col />
|
<col />
|
||||||
<col style="width: 30%" />
|
<col style="width: 30%" />
|
||||||
<col />
|
<col />
|
||||||
<col />
|
<col />
|
||||||
<col />
|
<col />
|
||||||
<col style="width: 20%" />
|
<col style="width: 20%" />
|
||||||
</colgroup>
|
</colgroup>
|
||||||
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Stunde</th>
|
<th>Stunde</th>
|
||||||
<th>Klasse(n)</th>
|
<th>Klasse(n)</th>
|
||||||
<th>(Fach)</th>
|
<th>(Fach)</th>
|
||||||
<th>Fach</th>
|
<th>Fach</th>
|
||||||
<th>Vertreter</th>
|
<th>Vertreter</th>
|
||||||
<th>(Raum)</th>
|
<th>(Raum)</th>
|
||||||
<th>Raum</th>
|
<th>Raum</th>
|
||||||
<th>Text</th>
|
<th>Text</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for subst in data.substitutions %}
|
{% for subst in data.substitutions %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ subst.period }}</td>
|
<td>{{ subst.period }}</td>
|
||||||
<td>{{ subst.classes|join(", ") }}</td>
|
<td>{{ subst.classes|join(", ") }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% match subst.prev_subject %}
|
{% match subst.prev_subject %}
|
||||||
{% when Some with (x) %}
|
{% when Some with (x) %}
|
||||||
{{ x }}
|
{{ x }}
|
||||||
{% when None %}
|
{% when None %}
|
||||||
---
|
---
|
||||||
{% endmatch %}
|
{% endmatch %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% match subst.subject %}
|
{% match subst.subject %}
|
||||||
{% when Some with (x) %}
|
{% when Some with (x) %}
|
||||||
{{ x }}
|
{{ x }}
|
||||||
{% when None %}
|
{% when None %}
|
||||||
---
|
---
|
||||||
{% endmatch %}
|
{% endmatch %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% match subst.teachers %}
|
{% match subst.teachers %}
|
||||||
{% when Some with (x) %}
|
{% when Some with (x) %}
|
||||||
{{ x|join(", ") }}
|
{{ x|join(", ") }}
|
||||||
{% when None %}
|
{% when None %}
|
||||||
---
|
---
|
||||||
{% endmatch %}
|
{% endmatch %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% match subst.prev_room %}
|
{% if subst.prev_rooms.is_empty() %}
|
||||||
{% when Some with (x) %}
|
---
|
||||||
{{ x }}
|
{% else %}
|
||||||
{% when None %}
|
{{ subst.prev_rooms|join(", ") }}
|
||||||
---
|
{% endif %}
|
||||||
{% endmatch %}
|
</td>
|
||||||
</td>
|
<td>
|
||||||
<td>
|
{% if subst.rooms.is_empty() %}
|
||||||
{% match subst.room %}
|
---
|
||||||
{% when Some with (x) %}
|
{% else %}
|
||||||
{{ x }}
|
{{ subst.rooms|join(", ") }}
|
||||||
{% when None %}
|
{% endif %}
|
||||||
---
|
</td>
|
||||||
{% endmatch %}
|
<td>
|
||||||
</td>
|
{% match subst.text %}
|
||||||
<td>
|
{% when Some with (x) %}
|
||||||
{% match subst.text %}
|
{{ x }}
|
||||||
{% when Some with (x) %}
|
{% when None %}
|
||||||
{{ x }}
|
{% endmatch %}
|
||||||
{% when None %}
|
</td>
|
||||||
{% endmatch %}
|
</tr>
|
||||||
</td>
|
{% endfor %}
|
||||||
</tr>
|
</tbody>
|
||||||
{% endfor %}
|
</table>
|
||||||
</tbody>
|
</main>
|
||||||
</table>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<footer id="footer">
|
<footer id="footer">
|
||||||
<div class="element">
|
<div class="element">
|
||||||
<p>
|
<p>
|
||||||
BVplan - der bessre Vertretungsplan sogar mit UTF-8 Support!
|
BVplan - der bessre Vertretungsplan sogar mit UTF-8 Support!
|
||||||
Wow
|
Wow
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a href="https://git.dergrimm.net/dergrimm/bvplan">
|
|
||||||
https://git.dergrimm.net/dergrimm/bvplan
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
<p class="element">
|
|
||||||
<code>
|
|
||||||
Powered by Dominic Grimm <<a
|
|
||||||
href="mailto:dominic@dergrimm.net"
|
|
||||||
>dominic@dergrimm.net</a
|
|
||||||
>>, Untis sucks
|
|
||||||
</code>
|
|
||||||
</p>
|
</p>
|
||||||
</footer>
|
<p>
|
||||||
|
<a href="https://git.dergrimm.net/dergrimm/bvplan">
|
||||||
|
https://git.dergrimm.net/dergrimm/bvplan
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<p class="element">
|
||||||
|
<code>
|
||||||
|
Powered by Dominic Grimm <<a
|
||||||
|
href="mailto:dominic@dergrimm.net"
|
||||||
|
>dominic@dergrimm.net</a
|
||||||
|
>>, Untis sucks
|
||||||
|
</code>
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
<script src="/static/js/bvplan.js"></script>
|
<script src="/static/js/bvplan.js"></script>
|
||||||
</body>
|
{% endblock %}
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,47 +1,16 @@
|
||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="de-DE">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<meta name="generator" content="BVplan" />
|
|
||||||
<title>BVplan | dergrimm.net</title>
|
|
||||||
|
|
||||||
<link rel="shortcut icon" href="/static/favicon.ico" />
|
{% block title %}{{ status_code.as_str() }}{% endblock %}
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
|
||||||
<link rel="manifest" href="/static/site.webmanifest">
|
|
||||||
|
|
||||||
<style>
|
{% block head %}{% endblock %}
|
||||||
body {
|
|
||||||
text-align: center;
|
{% block body %}
|
||||||
}
|
<h1>{{ status_code }}</h1>
|
||||||
</style>
|
{% match message %}
|
||||||
|
{% when Some with (x) %}
|
||||||
|
<hr />
|
||||||
|
<p>{{ x }}</p>
|
||||||
|
{% when None %}
|
||||||
|
{% endmatch %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
<!-- Matomo -->
|
|
||||||
<script>
|
|
||||||
var _paq = window._paq = window._paq || [];
|
|
||||||
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
|
||||||
_paq.push(['trackPageView']);
|
|
||||||
_paq.push(['enableLinkTracking']);
|
|
||||||
(function() {
|
|
||||||
var u="//matomo.dergrimm.net/";
|
|
||||||
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
|
||||||
_paq.push(['setSiteId', '6']);
|
|
||||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
|
||||||
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
<!-- End Matomo Code -->
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>{{ status_code }}</h1>
|
|
||||||
{% match message %}
|
|
||||||
{% when Some with (x) %}
|
|
||||||
<hr />
|
|
||||||
<p>{{ x }}</p>
|
|
||||||
{% when None %}
|
|
||||||
{% endmatch %}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
Loading…
Reference in a new issue