cal #735
2
TODO.md
Normal file
2
TODO.md
Normal file
@ -0,0 +1,2 @@
|
||||
- create new field in user table -> user\_token
|
||||
- change in misc.rs personal calendar function on not require User, but user\_token
|
@ -183,6 +183,17 @@ INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id",
|
||||
.unwrap() //TODO: fixme
|
||||
}
|
||||
|
||||
pub async fn all_with_user(db: &SqlitePool, user: &User) -> Vec<Event> {
|
||||
let mut ret = Vec::new();
|
||||
let events = Self::all(db).await;
|
||||
for event in events {
|
||||
if event.is_rower_registered(db, user).await {
|
||||
ret.push(event);
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
//TODO: add tests
|
||||
pub async fn is_rower_registered(&self, db: &SqlitePool, user: &User) -> bool {
|
||||
let is_rower = sqlx::query!(
|
||||
@ -394,16 +405,23 @@ WHERE trip_details.id=?
|
||||
|
||||
let events = Event::all(db).await;
|
||||
for event in events {
|
||||
let mut vevent =
|
||||
ics::Event::new(format!("{}@rudernlinz.at", event.id), "19900101T180000");
|
||||
calendar.add_event(event.get_vevent(db).await);
|
||||
}
|
||||
let mut buf = Vec::new();
|
||||
write!(&mut buf, "{}", calendar).unwrap();
|
||||
String::from_utf8(buf).unwrap()
|
||||
}
|
||||
|
||||
pub(crate) async fn get_vevent(self, db: &SqlitePool) -> ics::Event {
|
||||
let mut vevent = ics::Event::new(format!("{}@rudernlinz.at", self.id), "19900101T180000");
|
||||
vevent.push(DtStart::new(format!(
|
||||
"{}T{}00",
|
||||
event.day.replace('-', ""),
|
||||
event.planned_starting_time.replace(':', "")
|
||||
self.day.replace('-', ""),
|
||||
self.planned_starting_time.replace(':', "")
|
||||
)));
|
||||
let tripdetails = event.trip_details(db).await;
|
||||
let tripdetails = self.trip_details(db).await;
|
||||
let mut name = String::new();
|
||||
if event.is_cancelled() {
|
||||
if self.is_cancelled() {
|
||||
name.push_str("ABGESAGT");
|
||||
if let Some(notes) = &tripdetails.notes {
|
||||
if !notes.is_empty() {
|
||||
@ -413,17 +431,13 @@ WHERE trip_details.id=?
|
||||
|
||||
name.push_str("! :-( ");
|
||||
}
|
||||
name.push_str(&format!("{} ", event.name));
|
||||
name.push_str(&format!("{} ", self.name));
|
||||
|
||||
if let Some(triptype) = tripdetails.triptype(db).await {
|
||||
name.push_str(&format!("• {} ", triptype.name))
|
||||
}
|
||||
vevent.push(Summary::new(name));
|
||||
calendar.add_event(vevent);
|
||||
}
|
||||
let mut buf = Vec::new();
|
||||
write!(&mut buf, "{}", calendar).unwrap();
|
||||
String::from_utf8(buf).unwrap()
|
||||
vevent
|
||||
}
|
||||
|
||||
pub async fn trip_details(&self, db: &SqlitePool) -> TripDetails {
|
||||
|
23
src/model/personal/cal.rs
Normal file
23
src/model/personal/cal.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use std::io::Write;
|
||||
|
||||
use ics::ICalendar;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
use crate::model::{event::Event, trip::Trip, user::User};
|
||||
|
||||
pub(crate) async fn get_personal_cal(db: &SqlitePool, user: &User) -> String {
|
||||
let mut calendar = ICalendar::new("2.0", "ics-rs");
|
||||
|
||||
let events = Event::all_with_user(db, user).await;
|
||||
for event in events {
|
||||
calendar.add_event(event.get_vevent(db).await);
|
||||
}
|
||||
|
||||
let trips = Trip::all_with_user(db, user).await;
|
||||
for trip in trips {
|
||||
calendar.add_event(trip.get_vevent(db).await);
|
||||
}
|
||||
let mut buf = Vec::new();
|
||||
write!(&mut buf, "{}", calendar).unwrap();
|
||||
String::from_utf8(buf).unwrap()
|
||||
}
|
@ -5,6 +5,7 @@ use sqlx::SqlitePool;
|
||||
|
||||
use super::{logbook::Logbook, stat::Stat, user::User};
|
||||
|
||||
pub(crate) mod cal;
|
||||
pub(crate) mod equatorprice;
|
||||
pub(crate) mod rowingbadge;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
use chrono::{Local, NaiveDate};
|
||||
use ics::properties::{DtStart, Summary};
|
||||
use serde::Serialize;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
@ -9,6 +10,7 @@ use super::{
|
||||
tripdetails::TripDetails,
|
||||
triptype::TripType,
|
||||
user::{CoxUser, User},
|
||||
usertrip::UserTrip,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Clone, Debug)]
|
||||
@ -123,6 +125,61 @@ WHERE trip_details.id=?
|
||||
.ok()
|
||||
}
|
||||
|
||||
pub(crate) async fn get_vevent(self, db: &SqlitePool) -> ics::Event {
|
||||
let mut vevent = ics::Event::new(format!("{}@rudernlinz.at", self.id), "19900101T180000");
|
||||
vevent.push(DtStart::new(format!(
|
||||
"{}T{}00",
|
||||
self.day.replace('-', ""),
|
||||
self.planned_starting_time.replace(':', "")
|
||||
)));
|
||||
let mut name = String::new();
|
||||
if self.is_cancelled() {
|
||||
name.push_str("ABGESAGT");
|
||||
if let Some(notes) = &self.notes {
|
||||
if !notes.is_empty() {
|
||||
name.push_str(&format!(" (Grund: {notes})"))
|
||||
}
|
||||
}
|
||||
|
||||
name.push_str("! :-( ");
|
||||
}
|
||||
name.push_str(&format!("Ruderausfahrt mit {} ", self.cox_name));
|
||||
|
||||
vevent.push(Summary::new(name));
|
||||
vevent
|
||||
}
|
||||
|
||||
pub async fn all(db: &SqlitePool) -> Vec<Self> {
|
||||
sqlx::query_as!(
|
||||
Self,
|
||||
"
|
||||
SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, trip_details.notes, allow_guests, trip_type_id, always_show, is_locked
|
||||
FROM trip
|
||||
INNER JOIN trip_details ON trip.trip_details_id = trip_details.id
|
||||
INNER JOIN user ON trip.cox_id = user.id
|
||||
",
|
||||
)
|
||||
.fetch_all(db)
|
||||
.await
|
||||
.unwrap() //TODO: fixme
|
||||
}
|
||||
|
||||
pub async fn all_with_user(db: &SqlitePool, user: &User) -> Vec<Self> {
|
||||
let mut ret = Vec::new();
|
||||
let trips = Self::all(db).await;
|
||||
for trip in trips {
|
||||
if let Some(trip_details_id) = trip.trip_details_id {
|
||||
if UserTrip::find_by_userid_and_trip_detail_id(db, user.id, trip_details_id)
|
||||
.await
|
||||
.is_some()
|
||||
{
|
||||
ret.push(trip);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
pub async fn find_by_id(db: &SqlitePool, id: i64) -> Option<Self> {
|
||||
sqlx::query_as!(
|
||||
Self,
|
||||
@ -370,6 +427,10 @@ WHERE day=?
|
||||
trips.retain(|e| e.trip.always_show);
|
||||
trips
|
||||
}
|
||||
|
||||
fn is_cancelled(&self) -> bool {
|
||||
self.max_people == 0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -1,7 +1,7 @@
|
||||
use rocket::{get, http::ContentType, routes, Route, State};
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
use crate::model::event::Event;
|
||||
use crate::model::{event::Event, personal::cal::get_personal_cal, user::User};
|
||||
|
||||
#[get("/cal")]
|
||||
async fn cal(db: &State<SqlitePool>) -> (ContentType, String) {
|
||||
@ -9,8 +9,14 @@ async fn cal(db: &State<SqlitePool>) -> (ContentType, String) {
|
||||
(ContentType::Calendar, Event::get_ics_feed(db).await)
|
||||
}
|
||||
|
||||
#[get("/cal/registered")]
|
||||
async fn cal_registered(db: &State<SqlitePool>, user: User) -> (ContentType, String) {
|
||||
//TODO: add unit test once proper functionality is there
|
||||
(ContentType::Calendar, get_personal_cal(db, &user).await)
|
||||
}
|
||||
|
||||
pub fn routes() -> Vec<Route> {
|
||||
routes![cal]
|
||||
routes![cal, cal_registered]
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -103,7 +103,7 @@
|
||||
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
|
||||
role="alert">
|
||||
<h2 class="h2">
|
||||
Deine Ruderkarriere
|
||||
Dein Ruderleben
|
||||
<span class="text-xl"
|
||||
onclick="document.getElementById('call-for-action').showModal()">💡</span>
|
||||
</h2>
|
||||
@ -213,6 +213,21 @@
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
<div class="py-3">
|
||||
<p>
|
||||
<details>
|
||||
<summary><span class="text-xl"> 📅 </span> Kalender</summary>
|
||||
<p class="mt-3">
|
||||
Du möchtest immer up-to-date mit den Events und Ausfahrten bleiben? Wir bieten 3 verschiedene Arten von Kalender an:</p>
|
||||
<ol class="list-decimal ml-5 my-3">
|
||||
<li><strong>Alle Events und Ausfahrten</strong>, zu denen du dich angemeldet hast: <a class="underline" href="https://app.rudernlinz.at/cal/personal?my-secrect-key">https://app.rudernlinz.at/cal/personal?my-secrect-key</a></li>
|
||||
<li><strong>Allgemeiner Kalender</strong>, zB save-the-dates (Wanderfahrten, ...): <a href="https://rudernlinz.at/cal" class="underline">https://rudernlinz.at/cal</a></li>
|
||||
<li><strong>Alle Events</strong>: <a class="underline" href="https://app.rudernlinz.at/cal">https://app.rudernlinz.at/cal</a></li>
|
||||
</ol>
|
||||
Du kannst die Kalender einfach in deinen Kalender als "externen Kalender" synchronisieren. Die genauen Schritte hängen von deiner verwendeten Software ab.
|
||||
</details>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white dark:bg-primary-900 text-black dark:text-white rounded-md block shadow mt-5"
|
||||
|
Loading…
Reference in New Issue
Block a user