Skip to content

Commit

Permalink
Fix and deploy!
Browse files Browse the repository at this point in the history
  • Loading branch information
Cantido committed Jan 21, 2024
1 parent e7151a1 commit 802eb3d
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 14 deletions.
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.git
.github
target
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "waifu-calendar"
version = "0.1.0"
edition = "2021"
build = "build.rs"
authors = ["Rosa Richter"]
description = "A tool to fetch your favorite characters' birthdays from AniList"
repository = "https://github.com/Cantido/waifu-calendar"
Expand All @@ -18,7 +19,7 @@ name = "waifucal"
required-features = ["cli"]

[features]
default = ["cli"]
default = ["cli", "http"]
http = [
"ics",
"dep:axum",
Expand Down
38 changes: 38 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
FROM docker.io/rust:1-slim-bullseye AS build
WORKDIR /app

RUN apt update && apt upgrade && apt install -y pkg-config libssl-dev

COPY src /app/src
COPY build.rs Cargo.toml Cargo.lock /app/

RUN cargo build --locked --release --features http
RUN cp ./target/release/waifu-server /bin/server

FROM docker.io/debian:bullseye-slim AS final

RUN apt update && apt upgrade && apt install -y ca-certificates curl && apt-get clean

# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
USER appuser

COPY --from=build /bin/server /bin/

COPY assets /usr/local/share/waifu/assets
COPY templates /usr/local/share/waifu/templates

EXPOSE 8080

ENV WAIFU_ASSETS=/usr/local/share/waifu
ENV RUST_LOG=info

CMD ["/bin/server"]
22 changes: 22 additions & 0 deletions fly.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# fly.toml app configuration file generated for waifu-calendar on 2024-01-20T21:55:32-07:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = "waifu-calendar"
primary_region = "ord"

[build]

[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
processes = ["app"]

[[vm]]
cpu_kind = "shared"
cpus = 1
memory_mb = 1024
57 changes: 47 additions & 10 deletions src/http.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::{collections::HashMap, sync::Arc};
use std::{collections::HashMap, sync::Arc, path::PathBuf};

use axum::{Router, extract::{Query, State}, response::{Response, IntoResponse, Html}, http::{StatusCode, header}, routing::get};
use handlebars::{Handlebars, DirectorySourceOptions, to_json};
use log::{info, error};
use moka::future::Cache;
use recloser::{AsyncRecloser, Recloser};
use serde::Serialize;
Expand Down Expand Up @@ -31,9 +32,14 @@ impl<'a> AppState<'a> {
}

pub fn router() -> Result<Router> {
let mut assets_path = PathBuf::new();
assets_path.push(std::env::var("WAIFU_ASSETS").unwrap_or(".".to_string()));

info!("Loading assets from {:?}", assets_path);

let mut handlebars = Handlebars::new();
handlebars.set_strict_mode(true);
handlebars.register_templates_directory("templates", DirectorySourceOptions::default())?;
handlebars.register_templates_directory(assets_path.join("templates"), DirectorySourceOptions::default())?;

let circuit_breaker = AsyncRecloser::from(Recloser::default());

Expand All @@ -48,8 +54,8 @@ pub fn router() -> Result<Router> {
let router =
Router::new()
.route("/", get(get_index))
.route_service("/assets/pico.min.css", ServeFile::new("assets/pico.min.css"))
.route_service("/humans.txt", ServeFile::new("assets/humans.txt"))
.route_service("/assets/pico.min.css", ServeFile::new(assets_path.join("assets/pico.min.css")))
.route_service("/humans.txt", ServeFile::new(assets_path.join("assets/humans.txt")))
.route("/ics", get(get_birthday_ics))
.route("/cal", get(get_birthday_html))
.with_state(Arc::new(AppState::new(cache, handlebars, circuit_breaker)));
Expand Down Expand Up @@ -140,12 +146,43 @@ async fn get_birthday_html(State(state): State<Arc<AppState<'_>>>, Query(query):
} else {
state.circuit_breaker.call_with(should_melt, crate::get_waifu_birthdays(&username)).await
}
.map_err(|_| {
let body = state.handlebars.render("user_not_found", &NoHandlebarsData {}).unwrap();
(
StatusCode::NOT_FOUND,
Html::from(body),
).into_response()
.map_err(|e| {
match e {
recloser::Error::Inner(err) => {
match err.downcast::<crate::Error>() {
Ok(crate::Error::UserNotFound(_)) => {
let body = state.handlebars.render("user_not_found", &NoHandlebarsData {}).unwrap();
(
StatusCode::NOT_FOUND,
Html::from(body),
).into_response()
}
Err(err) => {
error!("Error contacting AniList: {:?}", err);
let body = state.handlebars.render("internal_server_error", &NoHandlebarsData {}).unwrap();
(
StatusCode::INTERNAL_SERVER_ERROR,
Html::from(body),
).into_response()
}
Ok(crate::Error::BadResponse) => {
error!("Unknown error fetching from AniList");
let body = state.handlebars.render("internal_server_error", &NoHandlebarsData {}).unwrap();
(
StatusCode::INTERNAL_SERVER_ERROR,
Html::from(body),
).into_response()
}
}
}
recloser::Error::Rejected => {
let body = state.handlebars.render("internal_server_error", &NoHandlebarsData {}).unwrap();
(
StatusCode::INTERNAL_SERVER_ERROR,
Html::from(body),
).into_response()
}
}
})?;

characters.sort_by_upcoming(&now);
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ pub async fn get_waifu_birthdays(username: &str) -> Result<Vec<Character>> {
let request_body = BirthdaysQuery::build_query(variables);

let client = reqwest::Client::new();
let res = client.post("https://graphql.anilist.co").json(&request_body).send().await?;
let res = client.post("https://graphql.anilist.co").header("User-Agent", "WaifuCalendar").json(&request_body).send().await?;
let response_body: Response<birthdays_query::ResponseData> = res.json().await?;

let data = response_body.data.ok_or(Error::BadResponse).with_context(|| "Missing response data")?;
Expand Down
4 changes: 2 additions & 2 deletions templates/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pre code {
}
</style>
<pre><code>
http://localhost:8080/ics?username=Owldown
https://waifu-calendar.fly.dev/ics?username=Owldown
</code></pre>
<p>
Of course, replacing the <code>username</code> with your own username.
Expand All @@ -48,7 +48,7 @@ http://localhost:8080/ics?username=Owldown
<form method="GET">
<label>
AniList username
<input id="username-field" name="username" autocomplete="username" type="text" minlength="2" maxlength="64" pattern="^[^\s]$" required />
<input id="username-field" name="username" autocomplete="username" type="text" minlength="2" maxlength="64" pattern="^[^\s]*$" required />
</label>
<button type="submit" formaction="/cal">View Calendar</button>
<button type="submit" formaction="/ics">Download ICS</button>
Expand Down

0 comments on commit 802eb3d

Please sign in to comment.