Compare commits
3 Commits
8ae429ac54
...
2326bb6e21
Author | SHA1 | Date | |
---|---|---|---|
2326bb6e21
|
|||
9017888794
|
|||
a69b8a9c55
|
14
.gitea/workflows/deploy.yml
Normal file
14
.gitea/workflows/deploy.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
name: Deploy application
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: host
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Run docker-compose
|
||||||
|
run: docker compose up -d --build
|
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -125,18 +125,6 @@ version = "1.10.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "caldendar-api"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"axum",
|
|
||||||
"chrono",
|
|
||||||
"icalendar",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"tokio",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.37"
|
version = "1.2.37"
|
||||||
@ -537,6 +525,18 @@ version = "5.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "recurring-event-api"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"axum",
|
||||||
|
"chrono",
|
||||||
|
"icalendar",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.26"
|
version = "0.1.26"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "caldendar-api"
|
name = "recurring-event-api"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
|
27
Containerfile
Normal file
27
Containerfile
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Use a Rust base image with Cargo installed
|
||||||
|
FROM rust:1.90 AS builder
|
||||||
|
LABEL authors="Martin Berg Alstad"
|
||||||
|
|
||||||
|
# Set the working directory inside the container
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
|
# Now copy the source code
|
||||||
|
COPY Cargo.toml Cargo.lock ./
|
||||||
|
COPY ./src ./src
|
||||||
|
|
||||||
|
# Build your application
|
||||||
|
RUN cargo build --release
|
||||||
|
|
||||||
|
# Start a new stage to create a smaller image without unnecessary build dependencies
|
||||||
|
FROM debian:trixie-slim
|
||||||
|
|
||||||
|
# Set the working directory
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
|
# Copy the built binary from the previous stage
|
||||||
|
COPY --from=builder /usr/src/app/target/release/recurring-event-api ./
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# Command to run the application
|
||||||
|
ENTRYPOINT ["./recurring-event-api"]
|
10
compose.yaml
Normal file
10
compose.yaml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
services:
|
||||||
|
recurring-event-api:
|
||||||
|
restart: unless-stopped
|
||||||
|
container_name: recurring-event-api
|
||||||
|
image: recurring-event-api
|
||||||
|
build:
|
||||||
|
dockerfile: Containerfile
|
||||||
|
context: .
|
||||||
|
ports:
|
||||||
|
- "8095:8000"
|
38
src/main.rs
38
src/main.rs
@ -8,6 +8,8 @@ use icalendar::{Calendar, Class, Component, Event, EventLike};
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::ops::Sub;
|
use std::ops::Sub;
|
||||||
|
|
||||||
|
const TEXT_CALENDAR: &'static str = "text/calendar";
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
enum Recurring {
|
enum Recurring {
|
||||||
Daily,
|
Daily,
|
||||||
@ -81,8 +83,6 @@ async fn get_calendar(Query(query): Query<EventQuery>) -> impl IntoResponse {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
const TEXT_CALENDAR: &'static str = "text/calendar";
|
|
||||||
|
|
||||||
async fn get_ics(Query(query): Query<EventQuery>) -> impl IntoResponse {
|
async fn get_ics(Query(query): Query<EventQuery>) -> impl IntoResponse {
|
||||||
let start = query.start_date_time;
|
let start = query.start_date_time;
|
||||||
let end = query
|
let end = query
|
||||||
@ -97,13 +97,15 @@ async fn get_ics(Query(query): Query<EventQuery>) -> impl IntoResponse {
|
|||||||
query.avoid_weekends.unwrap_or(false),
|
query.avoid_weekends.unwrap_or(false),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.for_each(|date| {
|
.for_each(|date_time| {
|
||||||
calendar.push(
|
let mut event = Event::new();
|
||||||
Event::new()
|
if query.all_day {
|
||||||
.summary(&query.title)
|
event.all_day(date_time.date());
|
||||||
.starts(date)
|
} else {
|
||||||
.class(Class::Confidential),
|
event.starts(date_time);
|
||||||
);
|
};
|
||||||
|
event.summary(&query.title).class(Class::Private);
|
||||||
|
calendar.push(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
Response::builder()
|
Response::builder()
|
||||||
@ -127,16 +129,15 @@ fn get_dates(
|
|||||||
Recurring::Weeky => todo!(),
|
Recurring::Weeky => todo!(),
|
||||||
Recurring::BiWeekly => todo!(),
|
Recurring::BiWeekly => todo!(),
|
||||||
Recurring::Monthly => {
|
Recurring::Monthly => {
|
||||||
let new_date = baseline.checked_add_months(Months::new(1)).unwrap();
|
baseline = baseline.checked_add_months(Months::new(1)).unwrap();
|
||||||
baseline = new_date;
|
|
||||||
if let true = avoid_weekends {
|
if let true = avoid_weekends {
|
||||||
match new_date.weekday() {
|
match baseline.weekday() {
|
||||||
Weekday::Sat => new_date.sub(TimeDelta::days(1)),
|
Weekday::Sat => baseline.sub(TimeDelta::days(1)),
|
||||||
Weekday::Sun => new_date.sub(TimeDelta::days(2)),
|
Weekday::Sun => baseline.sub(TimeDelta::days(2)),
|
||||||
_ => new_date,
|
_ => baseline,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new_date
|
baseline
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Recurring::Quarterly => todo!(),
|
Recurring::Quarterly => todo!(),
|
||||||
@ -150,10 +151,13 @@ fn get_dates(
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
const PORT: &'static str = "8000";
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(get_calendar))
|
.route("/", get(get_calendar))
|
||||||
.route("/ics", get(get_ics));
|
.route("/ics", get(get_ics));
|
||||||
|
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:8000").await.unwrap();
|
println!("Starting Application on port {PORT}");
|
||||||
|
|
||||||
|
let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{PORT}")).await.unwrap();
|
||||||
axum::serve(listener, app).await.unwrap();
|
axum::serve(listener, app).await.unwrap();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user