Update
This commit is contained in:
parent
19c3d876a2
commit
b25c20ab69
10 changed files with 472 additions and 365 deletions
|
@ -26,6 +26,7 @@ LABEL maintainer="Dominic Grimm <dominic@dergrimm.net>" \
|
|||
RUN apt update
|
||||
RUN apt install -y libpq5
|
||||
RUN apt install -y ca-certificates
|
||||
RUN apt install -y tzdata
|
||||
RUN apt-get clean
|
||||
RUN apt-get autoremove -y
|
||||
RUN rm -rf /var/lib/{apt,dpkg,cache,log}/
|
||||
|
|
|
@ -125,7 +125,7 @@ CREATE TABLE timegrid_time_unit (
|
|||
CREATE TYPE week_type AS ENUM ('a', 'b');
|
||||
|
||||
CREATE TABLE substitution_queries (
|
||||
id SERIAL PRIMARY KEY,
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
schoolyear_id INTEGER NOT NULL REFERENCES schoolyears(id),
|
||||
date DATE NOT NULL,
|
||||
week_type week_type NOT NULL,
|
||||
|
@ -153,8 +153,8 @@ CREATE TYPE substitution_type AS ENUM (
|
|||
);
|
||||
|
||||
CREATE TABLE substitutions(
|
||||
id SERIAL PRIMARY KEY,
|
||||
substitution_query_id INTEGER NOT NULL REFERENCES substitution_queries(id),
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
substitution_query_id BIGINT NOT NULL REFERENCES substitution_queries(id),
|
||||
subst_type substitution_type NOT NULL,
|
||||
lesson_id INTEGER NOT NULL,
|
||||
start_time TIME NOT NULL,
|
||||
|
@ -165,8 +165,8 @@ CREATE TABLE substitutions(
|
|||
);
|
||||
|
||||
CREATE TABLE substitution_classes (
|
||||
id SERIAL PRIMARY KEY,
|
||||
substitution_id INTEGER NOT NULL REFERENCES substitutions(id),
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
substitution_id BIGINT NOT NULL REFERENCES substitutions(id),
|
||||
position SMALLINT NOT NULL,
|
||||
class_id INTEGER NOT NULL REFERENCES classes(id),
|
||||
original_id INTEGER REFERENCES classes(id),
|
||||
|
@ -175,8 +175,8 @@ CREATE TABLE substitution_classes (
|
|||
);
|
||||
|
||||
CREATE TABLE substitution_teachers (
|
||||
id SERIAL PRIMARY KEY,
|
||||
substitution_id INTEGER NOT NULL REFERENCES substitutions(id),
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
substitution_id BIGINT NOT NULL REFERENCES substitutions(id),
|
||||
position SMALLINT NOT NULL,
|
||||
teacher_id INTEGER REFERENCES teachers(id),
|
||||
original_id INTEGER REFERENCES teachers(id),
|
||||
|
@ -185,8 +185,8 @@ CREATE TABLE substitution_teachers (
|
|||
);
|
||||
|
||||
CREATE TABLE substitution_subjects (
|
||||
id SERIAL PRIMARY KEY,
|
||||
substitution_id INTEGER NOT NULL REFERENCES substitutions(id),
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
substitution_id BIGINT NOT NULL REFERENCES substitutions(id),
|
||||
position SMALLINT NOT NULL,
|
||||
subject_id INTEGER NOT NULL REFERENCES subjects(id),
|
||||
original_id INTEGER REFERENCES subjects(id),
|
||||
|
@ -195,8 +195,8 @@ CREATE TABLE substitution_subjects (
|
|||
);
|
||||
|
||||
CREATE TABLE substitution_rooms (
|
||||
id SERIAL PRIMARY KEY,
|
||||
substitution_id INTEGER NOT NULL REFERENCES substitutions(id),
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
substitution_id BIGINT NOT NULL REFERENCES substitutions(id),
|
||||
position SMALLINT NOT NULL,
|
||||
room_id INTEGER REFERENCES rooms(id),
|
||||
original_id INTEGER REFERENCES rooms(id),
|
||||
|
|
|
@ -388,7 +388,7 @@ impl diesel::deserialize::FromSql<schema::sql_types::WeekType, diesel::pg::Pg> f
|
|||
#[diesel(table_name = schema::substitution_queries)]
|
||||
#[diesel(belongs_to(Schoolyear))]
|
||||
pub struct SubstitutionQuery {
|
||||
pub id: i32,
|
||||
pub id: i64,
|
||||
pub schoolyear_id: i32,
|
||||
pub date: NaiveDate,
|
||||
pub week_type: WeekType,
|
||||
|
@ -508,8 +508,8 @@ impl From<untis::RpcSubstitionType> for SubstitutionType {
|
|||
#[diesel(table_name = schema::substitutions)]
|
||||
#[diesel(belongs_to(SubstitutionQuery))]
|
||||
pub struct Substitution {
|
||||
pub id: i32,
|
||||
pub substitution_query_id: i32,
|
||||
pub id: i64,
|
||||
pub substitution_query_id: i64,
|
||||
pub subst_type: SubstitutionType,
|
||||
pub lesson_id: i32,
|
||||
pub start_time: NaiveTime,
|
||||
|
@ -522,7 +522,7 @@ pub struct Substitution {
|
|||
#[derive(Insertable, Debug)]
|
||||
#[diesel(table_name = schema::substitutions)]
|
||||
pub struct NewSubstitution<'a> {
|
||||
pub substitution_query_id: i32,
|
||||
pub substitution_query_id: i64,
|
||||
pub subst_type: SubstitutionType,
|
||||
pub lesson_id: i32,
|
||||
pub start_time: NaiveTime,
|
||||
|
@ -535,8 +535,8 @@ pub struct NewSubstitution<'a> {
|
|||
#[diesel(belongs_to(Substitution))]
|
||||
#[diesel(belongs_to(Class))]
|
||||
pub struct SubstitutionClass {
|
||||
pub id: i32,
|
||||
pub substitution_id: i32,
|
||||
pub id: i64,
|
||||
pub substitution_id: i64,
|
||||
pub position: i16,
|
||||
pub class_id: i32,
|
||||
pub original_id: Option<i32>,
|
||||
|
@ -547,7 +547,7 @@ pub struct SubstitutionClass {
|
|||
#[derive(Insertable, Debug)]
|
||||
#[diesel(table_name = schema::substitution_classes)]
|
||||
pub struct NewSubstitutionClass {
|
||||
pub substitution_id: i32,
|
||||
pub substitution_id: i64,
|
||||
pub position: i16,
|
||||
pub class_id: i32,
|
||||
pub original_id: Option<i32>,
|
||||
|
@ -558,8 +558,8 @@ pub struct NewSubstitutionClass {
|
|||
#[diesel(belongs_to(Substitution))]
|
||||
#[diesel(belongs_to(Teacher))]
|
||||
pub struct SubstitutionTeacher {
|
||||
pub id: i32,
|
||||
pub substitution_id: i32,
|
||||
pub id: i64,
|
||||
pub substitution_id: i64,
|
||||
pub position: i16,
|
||||
pub teacher_id: Option<i32>,
|
||||
pub original_id: Option<i32>,
|
||||
|
@ -570,7 +570,7 @@ pub struct SubstitutionTeacher {
|
|||
#[derive(Insertable, Debug)]
|
||||
#[diesel(table_name = schema::substitution_teachers)]
|
||||
pub struct NewSubstitutionTeacher {
|
||||
pub substitution_id: i32,
|
||||
pub substitution_id: i64,
|
||||
pub position: i16,
|
||||
pub teacher_id: Option<i32>,
|
||||
pub original_id: Option<i32>,
|
||||
|
@ -581,8 +581,8 @@ pub struct NewSubstitutionTeacher {
|
|||
#[diesel(belongs_to(Substitution))]
|
||||
#[diesel(belongs_to(Subject))]
|
||||
pub struct SubstitutionSubject {
|
||||
pub id: i32,
|
||||
pub substitution_id: i32,
|
||||
pub id: i64,
|
||||
pub substitution_id: i64,
|
||||
pub position: i16,
|
||||
pub subject_id: i32,
|
||||
pub original_id: Option<i32>,
|
||||
|
@ -593,7 +593,7 @@ pub struct SubstitutionSubject {
|
|||
#[derive(Insertable, Debug)]
|
||||
#[diesel(table_name = schema::substitution_subjects)]
|
||||
pub struct NewSubstitutionSubject {
|
||||
pub substitution_id: i32,
|
||||
pub substitution_id: i64,
|
||||
pub position: i16,
|
||||
pub subject_id: i32,
|
||||
pub original_id: Option<i32>,
|
||||
|
@ -604,8 +604,8 @@ pub struct NewSubstitutionSubject {
|
|||
#[diesel(belongs_to(Substitution))]
|
||||
#[diesel(belongs_to(Room))]
|
||||
pub struct SubstitutionRoom {
|
||||
pub id: i32,
|
||||
pub substitution_id: i32,
|
||||
pub id: i64,
|
||||
pub substitution_id: i64,
|
||||
pub position: i16,
|
||||
pub room_id: Option<i32>,
|
||||
pub original_id: Option<i32>,
|
||||
|
@ -616,7 +616,7 @@ pub struct SubstitutionRoom {
|
|||
#[derive(Insertable, Debug)]
|
||||
#[diesel(table_name = schema::substitution_rooms)]
|
||||
pub struct NewSubstitutionRoom {
|
||||
pub substitution_id: i32,
|
||||
pub substitution_id: i64,
|
||||
pub position: i16,
|
||||
pub room_id: Option<i32>,
|
||||
pub original_id: Option<i32>,
|
||||
|
|
|
@ -152,7 +152,7 @@ diesel::table! {
|
|||
use super::sql_types::*;
|
||||
|
||||
substitution_queries {
|
||||
id -> Integer,
|
||||
id -> BigInt,
|
||||
schoolyear_id -> Integer,
|
||||
date -> Date,
|
||||
week_type -> WeekType,
|
||||
|
@ -168,8 +168,8 @@ diesel::table! {
|
|||
use super::sql_types::*;
|
||||
|
||||
substitutions {
|
||||
id -> Integer,
|
||||
substitution_query_id -> Integer,
|
||||
id -> BigInt,
|
||||
substitution_query_id -> BigInt,
|
||||
subst_type -> SubstitutionType,
|
||||
lesson_id -> Integer,
|
||||
start_time -> Time,
|
||||
|
@ -182,8 +182,8 @@ diesel::table! {
|
|||
|
||||
diesel::table! {
|
||||
substitution_classes {
|
||||
id -> Integer,
|
||||
substitution_id -> Integer,
|
||||
id -> BigInt,
|
||||
substitution_id -> BigInt,
|
||||
position -> SmallInt,
|
||||
class_id -> Integer,
|
||||
original_id -> Nullable<Integer>,
|
||||
|
@ -194,8 +194,8 @@ diesel::table! {
|
|||
|
||||
diesel::table! {
|
||||
substitution_teachers {
|
||||
id -> Integer,
|
||||
substitution_id -> Integer,
|
||||
id -> BigInt,
|
||||
substitution_id -> BigInt,
|
||||
position -> SmallInt,
|
||||
teacher_id -> Nullable<Integer>,
|
||||
original_id -> Nullable<Integer>,
|
||||
|
@ -206,8 +206,8 @@ diesel::table! {
|
|||
|
||||
diesel::table! {
|
||||
substitution_subjects {
|
||||
id -> Integer,
|
||||
substitution_id -> Integer,
|
||||
id -> BigInt,
|
||||
substitution_id -> BigInt,
|
||||
position -> SmallInt,
|
||||
subject_id -> Integer,
|
||||
original_id -> Nullable<Integer>,
|
||||
|
@ -218,8 +218,8 @@ diesel::table! {
|
|||
|
||||
diesel::table! {
|
||||
substitution_rooms {
|
||||
id -> Integer,
|
||||
substitution_id -> Integer,
|
||||
id -> BigInt,
|
||||
substitution_id -> BigInt,
|
||||
position -> SmallInt,
|
||||
room_id -> Nullable<Integer>,
|
||||
original_id -> Nullable<Integer>,
|
||||
|
|
89
bvplan/src/worker/cleanup.rs
Normal file
89
bvplan/src/worker/cleanup.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
use anyhow::Result;
|
||||
use celery::{error::TaskError, task::TaskResult};
|
||||
use chrono::prelude::*;
|
||||
use diesel::prelude::*;
|
||||
|
||||
use crate::db;
|
||||
|
||||
fn do_cleanup(db_conn: &mut db::Connection) -> Result<()> {
|
||||
let timegrid_ids = db::schema::timegrids::table
|
||||
.select(db::schema::timegrids::id)
|
||||
.filter(db::schema::timegrids::active.eq(false))
|
||||
.load::<i32>(db_conn)?;
|
||||
let timegrid_day_ids = db::schema::timegrid_days::table
|
||||
.select(db::schema::timegrid_days::id)
|
||||
.filter(db::schema::timegrid_days::timegrid_id.eq_any(&timegrid_ids))
|
||||
.load::<i32>(db_conn)?;
|
||||
|
||||
diesel::delete(
|
||||
db::schema::timegrid_time_unit::table
|
||||
.filter(db::schema::timegrid_time_unit::timegrid_day_id.eq_any(&timegrid_day_ids)),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
diesel::delete(
|
||||
db::schema::timegrid_days::table
|
||||
.filter(db::schema::timegrid_days::id.eq_any(timegrid_day_ids)),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
diesel::delete(
|
||||
db::schema::timegrids::table.filter(db::schema::timegrids::id.eq_any(timegrid_ids)),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
let subst_query_ids = db::schema::substitution_queries::table
|
||||
.select(db::schema::substitution_queries::id)
|
||||
.filter(
|
||||
db::schema::substitution_queries::queried_at
|
||||
.lt(Local::now().naive_local() - chrono::Duration::hours(1)),
|
||||
)
|
||||
.load::<i64>(db_conn)?;
|
||||
let subst_ids = db::schema::substitutions::table
|
||||
.select(db::schema::substitutions::id)
|
||||
.filter(db::schema::substitutions::substitution_query_id.eq_any(&subst_query_ids))
|
||||
.load::<i64>(db_conn)?;
|
||||
|
||||
diesel::delete(
|
||||
db::schema::substitution_classes::table
|
||||
.filter(db::schema::substitution_classes::substitution_id.eq_any(&subst_ids)),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
diesel::delete(
|
||||
db::schema::substitution_teachers::table
|
||||
.filter(db::schema::substitution_teachers::substitution_id.eq_any(&subst_ids)),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
diesel::delete(
|
||||
db::schema::substitution_subjects::table
|
||||
.filter(db::schema::substitution_subjects::substitution_id.eq_any(&subst_ids)),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
diesel::delete(
|
||||
db::schema::substitution_rooms::table
|
||||
.filter(db::schema::substitution_rooms::substitution_id.eq_any(&subst_ids)),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
diesel::delete(
|
||||
db::schema::substitutions::table.filter(db::schema::substitutions::id.eq_any(subst_ids)),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
diesel::delete(
|
||||
db::schema::substitution_queries::table
|
||||
.filter(db::schema::substitution_queries::id.eq_any(subst_query_ids)),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[celery::task]
|
||||
pub async fn cleanup() -> TaskResult<()> {
|
||||
let db_conn = &mut match db::POOL.get() {
|
||||
Ok(x) => x,
|
||||
Err(e) => return Err(TaskError::UnexpectedError(format!("{:?}", e))),
|
||||
};
|
||||
if let Err(e) = do_cleanup(db_conn) {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -25,286 +25,11 @@ async fn get_schoolyear(client: &untis::Client, db_conn: &mut db::Connection) ->
|
|||
.first(db_conn)?)
|
||||
}
|
||||
|
||||
async fn fetch_current_tenant(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let tenant = client.current_tenant().await?;
|
||||
if diesel::select(diesel::dsl::not(diesel::dsl::exists(
|
||||
db::schema::tenants::table.filter(db::schema::tenants::untis_id.eq(tenant.id)),
|
||||
)))
|
||||
.get_result::<bool>(db_conn)?
|
||||
{
|
||||
diesel::update(db::schema::tenants::table)
|
||||
.filter(db::schema::tenants::active)
|
||||
.set(db::schema::tenants::active.eq(false))
|
||||
.execute(db_conn)?;
|
||||
diesel::insert_into(db::schema::tenants::table)
|
||||
.values(db::models::NewTenant {
|
||||
untis_id: tenant.id,
|
||||
schoolyear_id,
|
||||
name: &tenant.display_name,
|
||||
active: true,
|
||||
})
|
||||
.execute(db_conn)?;
|
||||
} else if diesel::select(diesel::dsl::exists(
|
||||
db::schema::tenants::table
|
||||
.filter(db::schema::tenants::untis_id.eq(tenant.id))
|
||||
.filter(db::schema::tenants::active.eq(false)),
|
||||
))
|
||||
.get_result::<bool>(db_conn)?
|
||||
{
|
||||
diesel::update(db::schema::tenants::table)
|
||||
.filter(db::schema::tenants::active)
|
||||
.set((
|
||||
db::schema::tenants::active.eq(false),
|
||||
db::schema::tenants::updated_at.eq(diesel::dsl::now),
|
||||
))
|
||||
.execute(db_conn)?;
|
||||
diesel::update(db::schema::tenants::table)
|
||||
.filter(db::schema::tenants::untis_id.eq(tenant.id))
|
||||
.set((
|
||||
db::schema::tenants::active.eq(true),
|
||||
db::schema::tenants::updated_at.eq(diesel::dsl::now),
|
||||
))
|
||||
.execute(db_conn)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_timegrid(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let days = client.timegrid().await?;
|
||||
|
||||
diesel::update(db::schema::timegrids::table)
|
||||
.filter(db::schema::timegrids::active)
|
||||
.set(db::schema::timegrids::active.eq(false))
|
||||
.execute(db_conn)?;
|
||||
let timegrid_id = diesel::insert_into(db::schema::timegrids::table)
|
||||
.values(db::models::NewTimegrid {
|
||||
schoolyear_id,
|
||||
active: true,
|
||||
})
|
||||
.returning(db::schema::timegrids::id)
|
||||
.get_result::<i32>(db_conn)?;
|
||||
|
||||
for day in days {
|
||||
let timegrid_day_id = diesel::insert_into(db::schema::timegrid_days::table)
|
||||
.values(db::models::NewTimegridDay {
|
||||
timegrid_id,
|
||||
weekday: day.day.try_into()?,
|
||||
})
|
||||
.returning(db::schema::timegrid_days::id)
|
||||
.get_result::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::timegrid_time_unit::table)
|
||||
.values(
|
||||
day.time_units
|
||||
.into_iter()
|
||||
.map(|x| db::models::NewTimegridTimeUnit {
|
||||
timegrid_day_id,
|
||||
start_time: x.start_time,
|
||||
end_time: x.end_time,
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_teachers(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let existing_teachers = db::schema::teachers::table
|
||||
.select(db::schema::teachers::untis_id)
|
||||
.filter(db::schema::teachers::schoolyear_id.eq(schoolyear_id))
|
||||
.load::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::teachers::table)
|
||||
.values(
|
||||
&client
|
||||
.teachers()
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|t| !existing_teachers.contains(&t.id))
|
||||
.map(|t| db::models::NewTeacher {
|
||||
untis_id: t.id,
|
||||
schoolyear_id,
|
||||
name: &t.name,
|
||||
forename: if t.forename.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(&t.forename)
|
||||
},
|
||||
display_name: &t.display_name,
|
||||
})
|
||||
.collect::<Vec<db::models::NewTeacher>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_classes(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let existing_classes = db::schema::classes::table
|
||||
.select(db::schema::classes::untis_id)
|
||||
.filter(db::schema::classes::schoolyear_id.eq(schoolyear_id))
|
||||
.load::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::classes::table)
|
||||
.values(
|
||||
&client
|
||||
.classes()
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|c| !existing_classes.contains(&c.id))
|
||||
.map(|c| db::models::NewClass {
|
||||
untis_id: c.id,
|
||||
schoolyear_id,
|
||||
name: &c.name,
|
||||
long_name: &c.long_name,
|
||||
active: c.active,
|
||||
})
|
||||
.collect::<Vec<db::models::NewClass>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_subjects(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let existing_classes = db::schema::subjects::table
|
||||
.select(db::schema::subjects::untis_id)
|
||||
.filter(db::schema::subjects::schoolyear_id.eq(schoolyear_id))
|
||||
.load::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::subjects::table)
|
||||
.values(
|
||||
&client
|
||||
.subjects()
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|c| !existing_classes.contains(&c.id))
|
||||
.map(|c| db::models::NewSubject {
|
||||
untis_id: c.id,
|
||||
schoolyear_id,
|
||||
name: &c.name,
|
||||
long_name: &c.long_name,
|
||||
})
|
||||
.collect::<Vec<db::models::NewSubject>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_rooms(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let existing_classes = db::schema::rooms::table
|
||||
.select(db::schema::rooms::untis_id)
|
||||
.filter(db::schema::rooms::schoolyear_id.eq(schoolyear_id))
|
||||
.load::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::rooms::table)
|
||||
.values(
|
||||
&client
|
||||
.rooms()
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|c| !existing_classes.contains(&c.id))
|
||||
.map(|c| db::models::NewRoom {
|
||||
untis_id: c.id,
|
||||
schoolyear_id,
|
||||
name: &c.name,
|
||||
long_name: &c.long_name,
|
||||
})
|
||||
.collect::<Vec<db::models::NewRoom>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_departments(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let existing_classes = db::schema::departments::table
|
||||
.select(db::schema::departments::untis_id)
|
||||
.filter(db::schema::departments::schoolyear_id.eq(schoolyear_id))
|
||||
.load::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::departments::table)
|
||||
.values(
|
||||
&client
|
||||
.departments()
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|c| !existing_classes.contains(&c.id))
|
||||
.map(|c| db::models::NewDepartment {
|
||||
untis_id: c.id,
|
||||
schoolyear_id,
|
||||
name: &c.name,
|
||||
long_name: &c.long_name,
|
||||
})
|
||||
.collect::<Vec<db::models::NewDepartment>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_holidays(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let existing_classes = db::schema::holidays::table
|
||||
.select(db::schema::holidays::untis_id)
|
||||
.filter(db::schema::holidays::schoolyear_id.eq(schoolyear_id))
|
||||
.load::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::holidays::table)
|
||||
.values(
|
||||
&client
|
||||
.holidays()
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|c| !existing_classes.contains(&c.id))
|
||||
.map(|c| db::models::NewHoliday {
|
||||
untis_id: c.id,
|
||||
schoolyear_id,
|
||||
name: &c.name,
|
||||
long_name: &c.long_name,
|
||||
start_date: c.start_date,
|
||||
end_date: c.end_date,
|
||||
})
|
||||
.collect::<Vec<db::models::NewHoliday>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_substitutions(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
db_conn: &mut db::Connection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<i32> {
|
||||
) -> Result<i64> {
|
||||
lazy_static! {
|
||||
static ref TITLE_SELECTOR: scraper::Selector =
|
||||
scraper::Selector::parse(".mon_title").unwrap();
|
||||
|
@ -362,7 +87,7 @@ async fn fetch_substitutions(
|
|||
queried_at: Utc::now().naive_utc(),
|
||||
})
|
||||
.returning(db::schema::substitution_queries::id)
|
||||
.get_result::<i32>(db_conn)?;
|
||||
.get_result::<i64>(db_conn)?;
|
||||
|
||||
for substitution in client.substitutions(&date, &date, None).await? {
|
||||
let substitution_id = diesel::insert_into(db::schema::substitutions::table)
|
||||
|
@ -375,7 +100,7 @@ async fn fetch_substitutions(
|
|||
text: substitution.text.as_deref(),
|
||||
})
|
||||
.returning(db::schema::substitutions::id)
|
||||
.get_result::<i32>(db_conn)?;
|
||||
.get_result::<i64>(db_conn)?;
|
||||
|
||||
diesel::insert_into(db::schema::substitution_classes::table)
|
||||
.values(
|
||||
|
@ -525,7 +250,7 @@ fn get_period(times: &Vec<StartEndTime>, start: bool, time: NaiveTime) -> Option
|
|||
fn cache_substitutions(
|
||||
db_conn: &mut PgConnection,
|
||||
redis_conn: &mut cache::Connection,
|
||||
substitution_query_id: i32,
|
||||
substitution_query_id: i64,
|
||||
last_import_time: NaiveDateTime,
|
||||
) -> Result<()> {
|
||||
let (queried_at, date, week_type) = db::schema::substitution_queries::table
|
||||
|
@ -717,7 +442,7 @@ fn cache_substitutions(
|
|||
}
|
||||
|
||||
#[celery::task]
|
||||
pub async fn update_info() -> TaskResult<()> {
|
||||
pub async fn get_substitutions() -> TaskResult<()> {
|
||||
let dur = Duration::from_secs(2);
|
||||
|
||||
thread::sleep(dur);
|
||||
|
@ -744,38 +469,6 @@ pub async fn update_info() -> TaskResult<()> {
|
|||
Err(e) => return Err(TaskError::UnexpectedError(format!("{:?}", e))),
|
||||
};
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_current_tenant(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_timegrid(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_teachers(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_classes(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_subjects(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_rooms(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_departments(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_holidays(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
let last_import_time = match client.last_import_time().await {
|
||||
Ok(x) => x,
|
||||
Err(e) => return Err(TaskError::UnexpectedError(format!("{:?}", e))),
|
|
@ -7,7 +7,8 @@ use stdext::duration::DurationExt;
|
|||
|
||||
use crate::config;
|
||||
|
||||
pub mod update_info;
|
||||
pub mod cleanup;
|
||||
pub mod get_substitutions;
|
||||
pub mod update_meta;
|
||||
|
||||
pub const QUEUE_NAME: &str = "celery";
|
||||
|
@ -22,8 +23,9 @@ pub async fn init() {
|
|||
celery::app!(
|
||||
broker = AMQPBroker { &config::CONFIG.amqp_url },
|
||||
tasks = [
|
||||
update_info::update_info,
|
||||
get_substitutions::get_substitutions,
|
||||
update_meta::update_meta,
|
||||
cleanup::cleanup,
|
||||
],
|
||||
task_routes = [
|
||||
"*" => QUEUE_NAME,
|
||||
|
@ -45,15 +47,20 @@ pub fn beat() -> impl std::future::Future<
|
|||
celery::beat!(
|
||||
broker = AMQPBroker { &config::CONFIG.amqp_url },
|
||||
tasks = [
|
||||
"update_info" => {
|
||||
update_info::update_info,
|
||||
schedule = DeltaSchedule::new(Duration::from_minutes(999)),
|
||||
"get_substitutions" => {
|
||||
get_substitutions::get_substitutions,
|
||||
schedule = DeltaSchedule::new(Duration::from_minutes(5)),
|
||||
args = (),
|
||||
},
|
||||
"update_meta" => {
|
||||
update_meta::update_meta,
|
||||
schedule = DeltaSchedule::new(Duration::from_hours(6)),
|
||||
args = (),
|
||||
},
|
||||
"cleanup" => {
|
||||
cleanup::cleanup,
|
||||
schedule = DeltaSchedule::new(Duration::from_hours(1)),
|
||||
args = (),
|
||||
}
|
||||
],
|
||||
task_routes = [
|
||||
|
|
|
@ -43,6 +43,281 @@ async fn fetch_schoolyears(client: &untis::Client, db_conn: &mut db::Connection)
|
|||
Ok(id)
|
||||
}
|
||||
|
||||
async fn fetch_current_tenant(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let tenant = client.current_tenant().await?;
|
||||
if diesel::select(diesel::dsl::not(diesel::dsl::exists(
|
||||
db::schema::tenants::table.filter(db::schema::tenants::untis_id.eq(tenant.id)),
|
||||
)))
|
||||
.get_result::<bool>(db_conn)?
|
||||
{
|
||||
diesel::update(db::schema::tenants::table)
|
||||
.filter(db::schema::tenants::active)
|
||||
.set(db::schema::tenants::active.eq(false))
|
||||
.execute(db_conn)?;
|
||||
diesel::insert_into(db::schema::tenants::table)
|
||||
.values(db::models::NewTenant {
|
||||
untis_id: tenant.id,
|
||||
schoolyear_id,
|
||||
name: &tenant.display_name,
|
||||
active: true,
|
||||
})
|
||||
.execute(db_conn)?;
|
||||
} else if diesel::select(diesel::dsl::exists(
|
||||
db::schema::tenants::table
|
||||
.filter(db::schema::tenants::untis_id.eq(tenant.id))
|
||||
.filter(db::schema::tenants::active.eq(false)),
|
||||
))
|
||||
.get_result::<bool>(db_conn)?
|
||||
{
|
||||
diesel::update(db::schema::tenants::table)
|
||||
.filter(db::schema::tenants::active)
|
||||
.set((
|
||||
db::schema::tenants::active.eq(false),
|
||||
db::schema::tenants::updated_at.eq(diesel::dsl::now),
|
||||
))
|
||||
.execute(db_conn)?;
|
||||
diesel::update(db::schema::tenants::table)
|
||||
.filter(db::schema::tenants::untis_id.eq(tenant.id))
|
||||
.set((
|
||||
db::schema::tenants::active.eq(true),
|
||||
db::schema::tenants::updated_at.eq(diesel::dsl::now),
|
||||
))
|
||||
.execute(db_conn)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_timegrid(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let days = client.timegrid().await?;
|
||||
|
||||
diesel::update(db::schema::timegrids::table)
|
||||
.filter(db::schema::timegrids::active)
|
||||
.set(db::schema::timegrids::active.eq(false))
|
||||
.execute(db_conn)?;
|
||||
let timegrid_id = diesel::insert_into(db::schema::timegrids::table)
|
||||
.values(db::models::NewTimegrid {
|
||||
schoolyear_id,
|
||||
active: true,
|
||||
})
|
||||
.returning(db::schema::timegrids::id)
|
||||
.get_result::<i32>(db_conn)?;
|
||||
|
||||
for day in days {
|
||||
let timegrid_day_id = diesel::insert_into(db::schema::timegrid_days::table)
|
||||
.values(db::models::NewTimegridDay {
|
||||
timegrid_id,
|
||||
weekday: day.day.try_into()?,
|
||||
})
|
||||
.returning(db::schema::timegrid_days::id)
|
||||
.get_result::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::timegrid_time_unit::table)
|
||||
.values(
|
||||
day.time_units
|
||||
.into_iter()
|
||||
.map(|x| db::models::NewTimegridTimeUnit {
|
||||
timegrid_day_id,
|
||||
start_time: x.start_time,
|
||||
end_time: x.end_time,
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_teachers(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let existing_teachers = db::schema::teachers::table
|
||||
.select(db::schema::teachers::untis_id)
|
||||
.filter(db::schema::teachers::schoolyear_id.eq(schoolyear_id))
|
||||
.load::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::teachers::table)
|
||||
.values(
|
||||
&client
|
||||
.teachers()
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|t| !existing_teachers.contains(&t.id))
|
||||
.map(|t| db::models::NewTeacher {
|
||||
untis_id: t.id,
|
||||
schoolyear_id,
|
||||
name: &t.name,
|
||||
forename: if t.forename.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(&t.forename)
|
||||
},
|
||||
display_name: &t.display_name,
|
||||
})
|
||||
.collect::<Vec<db::models::NewTeacher>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_classes(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let existing_classes = db::schema::classes::table
|
||||
.select(db::schema::classes::untis_id)
|
||||
.filter(db::schema::classes::schoolyear_id.eq(schoolyear_id))
|
||||
.load::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::classes::table)
|
||||
.values(
|
||||
&client
|
||||
.classes()
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|c| !existing_classes.contains(&c.id))
|
||||
.map(|c| db::models::NewClass {
|
||||
untis_id: c.id,
|
||||
schoolyear_id,
|
||||
name: &c.name,
|
||||
long_name: &c.long_name,
|
||||
active: c.active,
|
||||
})
|
||||
.collect::<Vec<db::models::NewClass>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_subjects(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let existing_classes = db::schema::subjects::table
|
||||
.select(db::schema::subjects::untis_id)
|
||||
.filter(db::schema::subjects::schoolyear_id.eq(schoolyear_id))
|
||||
.load::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::subjects::table)
|
||||
.values(
|
||||
&client
|
||||
.subjects()
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|c| !existing_classes.contains(&c.id))
|
||||
.map(|c| db::models::NewSubject {
|
||||
untis_id: c.id,
|
||||
schoolyear_id,
|
||||
name: &c.name,
|
||||
long_name: &c.long_name,
|
||||
})
|
||||
.collect::<Vec<db::models::NewSubject>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_rooms(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let existing_classes = db::schema::rooms::table
|
||||
.select(db::schema::rooms::untis_id)
|
||||
.filter(db::schema::rooms::schoolyear_id.eq(schoolyear_id))
|
||||
.load::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::rooms::table)
|
||||
.values(
|
||||
&client
|
||||
.rooms()
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|c| !existing_classes.contains(&c.id))
|
||||
.map(|c| db::models::NewRoom {
|
||||
untis_id: c.id,
|
||||
schoolyear_id,
|
||||
name: &c.name,
|
||||
long_name: &c.long_name,
|
||||
})
|
||||
.collect::<Vec<db::models::NewRoom>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_departments(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let existing_classes = db::schema::departments::table
|
||||
.select(db::schema::departments::untis_id)
|
||||
.filter(db::schema::departments::schoolyear_id.eq(schoolyear_id))
|
||||
.load::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::departments::table)
|
||||
.values(
|
||||
&client
|
||||
.departments()
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|c| !existing_classes.contains(&c.id))
|
||||
.map(|c| db::models::NewDepartment {
|
||||
untis_id: c.id,
|
||||
schoolyear_id,
|
||||
name: &c.name,
|
||||
long_name: &c.long_name,
|
||||
})
|
||||
.collect::<Vec<db::models::NewDepartment>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_holidays(
|
||||
client: &untis::Client,
|
||||
db_conn: &mut PgConnection,
|
||||
schoolyear_id: i32,
|
||||
) -> Result<()> {
|
||||
let existing_classes = db::schema::holidays::table
|
||||
.select(db::schema::holidays::untis_id)
|
||||
.filter(db::schema::holidays::schoolyear_id.eq(schoolyear_id))
|
||||
.load::<i32>(db_conn)?;
|
||||
diesel::insert_into(db::schema::holidays::table)
|
||||
.values(
|
||||
&client
|
||||
.holidays()
|
||||
.await?
|
||||
.iter()
|
||||
.filter(|c| !existing_classes.contains(&c.id))
|
||||
.map(|c| db::models::NewHoliday {
|
||||
untis_id: c.id,
|
||||
schoolyear_id,
|
||||
name: &c.name,
|
||||
long_name: &c.long_name,
|
||||
start_date: c.start_date,
|
||||
end_date: c.end_date,
|
||||
})
|
||||
.collect::<Vec<db::models::NewHoliday>>(),
|
||||
)
|
||||
.execute(db_conn)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[celery::task]
|
||||
pub async fn update_meta() -> TaskResult<()> {
|
||||
let dur = Duration::from_secs(2);
|
||||
|
@ -50,6 +325,11 @@ pub async fn update_meta() -> TaskResult<()> {
|
|||
Ok(x) => x,
|
||||
Err(e) => return Err(TaskError::UnexpectedError(format!("{:?}", e))),
|
||||
};
|
||||
if let Err(e) = client.login().await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
|
||||
let db_conn = &mut match db::POOL.get() {
|
||||
Ok(x) => x,
|
||||
Err(e) => return Err(TaskError::UnexpectedError(format!("{:?}", e))),
|
||||
|
@ -60,8 +340,38 @@ pub async fn update_meta() -> TaskResult<()> {
|
|||
Ok(x) => x,
|
||||
Err(e) => return Err(TaskError::UnexpectedError(format!("{:?}", e))),
|
||||
};
|
||||
dbg!(&schoolyear_id);
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_current_tenant(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_timegrid(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_teachers(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_classes(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_subjects(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_rooms(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_departments(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
thread::sleep(dur);
|
||||
if let Err(e) = fetch_holidays(&client, db_conn, schoolyear_id).await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
}
|
||||
|
||||
if let Err(e) = client.logout().await {
|
||||
return Err(TaskError::UnexpectedError(format!("{:?}", e)));
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<meta name="generator" content="BVplan" />
|
||||
|
||||
<script id="data" type="application/json">{{ data.substitutions.len()|json|safe }}</script>
|
||||
<script id="data-element-count" type="application/json">{{ data.substitutions.len()|json|safe }}</script>
|
||||
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"
|
||||
|
@ -227,8 +227,8 @@
|
|||
Wow
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://git.dergrimm.net/bvplan">
|
||||
https://git.dergrimm.net/bvplan
|
||||
<a href="https://git.dergrimm.net/dergrimm/bvplan">
|
||||
https://git.dergrimm.net/dergrimm/bvplan
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -252,10 +252,14 @@
|
|||
}, 30_000);
|
||||
};
|
||||
|
||||
const elementCount = JSON.parse($("#data").text());
|
||||
const elementCount = JSON.parse($("#data-element-count").text());
|
||||
const waitDelay = 10_000;
|
||||
const scrollDuration = elementCount * 200;
|
||||
|
||||
function reload() {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
function scrollUp() {
|
||||
$("html, body").animate(
|
||||
{
|
||||
|
@ -264,9 +268,7 @@
|
|||
scrollDuration,
|
||||
"linear"
|
||||
);
|
||||
setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, scrollDuration);
|
||||
setTimeout(reload, scrollDuration);
|
||||
}
|
||||
|
||||
function scrollDown() {
|
||||
|
@ -281,7 +283,7 @@
|
|||
}
|
||||
|
||||
window.scrollTo(0, 0);
|
||||
setTimeout(scrollDown, waitDelay);
|
||||
setTimeout($(window).height() > $(window).height() ? scrollDown : reload, waitDelay);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -83,6 +83,8 @@ services:
|
|||
<<: *bvplan
|
||||
command: worker
|
||||
volumes:
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ./data/backups:/backups
|
||||
|
||||
web:
|
||||
|
@ -93,6 +95,9 @@ services:
|
|||
- rabbitmq
|
||||
- worker
|
||||
- redis
|
||||
volumes:
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
|
||||
volumes:
|
||||
db:
|
||||
|
|
Loading…
Reference in a new issue