Skip to content

Commit

Permalink
refactor: organize code
Browse files Browse the repository at this point in the history
  • Loading branch information
dancixx committed Dec 4, 2024
1 parent daf59b0 commit 8270b77
Show file tree
Hide file tree
Showing 8 changed files with 336 additions and 317 deletions.
20 changes: 10 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use leptos::prelude::*;
use leptos_meta::Title;
use leptos_router::components::A;

use crate::api::{select_posts, select_tags};
use crate::loader;
use crate::server::{select_posts, select_tags};

#[component]
pub fn Component() -> impl IntoView {
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#![feature(async_closure)]

pub mod api;
pub mod app;
pub mod error_template;
pub mod home;
pub mod loader;
pub mod post;
#[cfg(feature = "ssr")]
pub mod redirect;
pub mod server;
#[cfg(feature = "ssr")]
pub mod server_utils;

#[cfg(feature = "hydrate")]
#[wasm_bindgen::prelude::wasm_bindgen]
Expand Down
134 changes: 3 additions & 131 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
#[cfg(feature = "ssr")]
#[tokio::main]
async fn main() {
use axum::extract::State;
use axum::response::Response;
use axum::{routing::get, Router};
use blog::api::{process_markdown, Post};
use blog::app::{shell, App};
use blog::redirect::redirect_www;
use blog::server_utils::connect;
use blog::server_utils::{rss_handler, sitemap_handler};
use blog::ssr::AppState;
use chrono::{DateTime, Utc};
use dotenvy::dotenv;
use leptos::logging;
use leptos::prelude::*;
use leptos_axum::{generate_route_list, LeptosRoutes};
use serde::{Deserialize, Serialize};
use std::env;
use surrealdb::engine::remote::http::Client;
use surrealdb::{
engine::remote::http::{Http, Https},
opt::auth::Root,
Surreal,
};
use tower_http::compression::predicate::{NotForContentType, SizeAbove};
use tower_http::compression::{CompressionLayer, Predicate};
use tower_http::trace::TraceLayer;
Expand Down Expand Up @@ -48,126 +39,7 @@ async fn main() {
let addr = leptos_options.site_addr;
let routes = generate_route_list(App);

let protocol = env::var("SURREAL_PROTOCOL").unwrap_or("http".to_string());
let host = env::var("SURREAL_HOST").unwrap_or("127.0.0.1:8000".to_string());
let username = env::var("SURREAL_ROOT_USER").unwrap_or("root".to_string());
let password = env::var("SURREAL_ROOT_PASS").unwrap_or("root".to_string());
let ns = env::var("SURREAL_NS").unwrap_or("rustblog".to_string());
let db_name = env::var("SURREAL_DB").unwrap_or("rustblog".to_string());

let db = if protocol == "http" {
Surreal::new::<Http>(host).await.unwrap()
} else {
Surreal::new::<Https>(host).await.unwrap()
};

db.signin(Root {
username: &username,
password: &password,
})
.await
.unwrap();
db.use_ns(ns).use_db(db_name).await.unwrap();

async fn generate_rss(db: Surreal<Client>) -> Result<String, ServerFnError> {
use rss::{ChannelBuilder, Item};
use std::sync::Arc;
use tokio::sync::Mutex;

let query = db.query("SELECT *, author.* from post WHERE is_published = true ORDER BY created_at DESC;").await;
let mut posts = query?.take::<Vec<Post>>(0)?;
posts.iter_mut().for_each(|post| {
let date_time = DateTime::parse_from_rfc3339(&post.created_at)
.unwrap()
.with_timezone(&Utc);
let naive_date = date_time.date_naive();
let formatted_date = naive_date.format("%b %-d").to_string();
post.created_at = formatted_date.into();
});
let posts = Arc::new(Mutex::new(posts));
let mut handles = vec![];

for _ in 0..posts.lock().await.len() {
let posts_clone = Arc::clone(&posts);
let handle = tokio::spawn(async move {
let mut posts = posts_clone.lock().await;
if let Some(post) = posts.iter_mut().next() {
post.body = process_markdown(post.body.to_string())
.await.unwrap().into();
}
});

handles.push(handle);
}

for handle in handles {
handle.await?;
}

let channel = ChannelBuilder::default()
.title("Rust-DD")
.link("https://rust-dd.com")
.description("Tech Diaries - The Official Rust-DD Developer Blog")
.items(
posts
.lock()
.await
.clone()
.into_iter()
.map(|post| {
let mut item = Item::default();
item.set_author(post.author.name.to_string());
item.set_title(post.title.to_string());
item.set_description(post.body.to_string());
item.set_link(format!("https://rust-dd.com/post/{}", post.slug.unwrap()));
item.set_pub_date(post.created_at.to_string());
item
})
.collect::<Vec<_>>(),
)
.build();

Ok(channel.to_string())
}

async fn rss_handler(State(state): State<AppState>) -> Response<String> {
let AppState { db, .. } = state;
let rss = generate_rss(db).await.unwrap();
Response::builder()
.header("Content-Type", "application/xml")
.body(rss)
.unwrap()
}

async fn sitemap_handler(State(state): State<AppState>) -> Response<String> {
#[derive(Serialize, Deserialize)]
struct Post {
slug: Option<String>,
created_at: String,
}

let AppState { db, .. } = state;
let query = db.query("SELECT slug, created_at FROM post WHERE is_published = true ORDER BY created_at DESC;").await;
let posts = query.unwrap().take::<Vec<Post>>(0).unwrap();
let mut sitemap = String::new();
sitemap.push_str("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
sitemap.push_str("<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n");
for post in posts {
sitemap.push_str("<url>\n");
sitemap.push_str(&format!(
"<loc>https://rust-dd.com/post/{}</loc>\n",
post.slug.unwrap()
));
sitemap.push_str(&format!("<lastmod>{}</lastmod>\n", post.created_at));
sitemap.push_str("</url>\n");
}
sitemap.push_str("</urlset>");
Response::builder()
.header("Content-Type", "application/xml")
.body(sitemap)
.unwrap()
}

let db = connect().await;
let app_state = AppState {
db,
leptos_options: leptos_options.clone(),
Expand Down
2 changes: 1 addition & 1 deletion src/post.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use leptos::prelude::*;
use leptos_meta::*;
use leptos_router::hooks::use_params_map;

use crate::api::{increment_views, select_post};
use crate::loader;
use crate::server::{increment_views, select_post};

#[component]
pub fn Component() -> impl IntoView {
Expand Down
10 changes: 7 additions & 3 deletions src/redirect.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
use axum::{
body::Body,
http::{Request, Response, StatusCode},
middleware::Next
middleware::Next,
};

pub async fn redirect_www(req: Request<Body>, next: Next) -> Result<Response<Body>, StatusCode> {
if let Some(host) = req.headers().get("host") {
if let Ok(host) = host.to_str() {
if host.starts_with("www.") {
let new_host = host.trim_start_matches("www.");
let new_uri = format!("https://{}{}", new_host, req.uri().path_and_query().map(|x| x.as_str()).unwrap_or(""));
let new_uri = format!(
"https://{}{}",
new_host,
req.uri().path_and_query().map(|x| x.as_str()).unwrap_or("")
);
let response = Response::builder()
.status(StatusCode::MOVED_PERMANENTLY)
.header("location", new_uri)
Expand All @@ -20,4 +24,4 @@ pub async fn redirect_www(req: Request<Body>, next: Next) -> Result<Response<Bod
}
}
Ok(next.run(req).await)
}
}
Loading

0 comments on commit 8270b77

Please sign in to comment.