Gonna finally make a good website
This commit is contained in:
parent
2b02ffb79f
commit
aac5804d95
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
target
|
||||||
|
.idea
|
||||||
1377
Cargo.lock
generated
Normal file
1377
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
9
Cargo.toml
Normal file
9
Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "yyyi_ru"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
axum = "0.8.3"
|
||||||
|
tokio = { version = "1.44.1", features = ["rt-multi-thread"] }
|
||||||
|
tera="1.20.0"
|
||||||
12
assets/HypertextPages/blog.html
Normal file
12
assets/HypertextPages/blog.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="/assets/css/common.css">
|
||||||
|
<title>Блог Гриши</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
21
assets/HypertextPages/index.html
Normal file
21
assets/HypertextPages/index.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="/assets/css/common.css">
|
||||||
|
<title>Гришина заглавная страничка</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="main-container">
|
||||||
|
<div>
|
||||||
|
<h2 class=""> Обо мне </h2>
|
||||||
|
<p class="description-text">
|
||||||
|
Я Андреев Григорий, от 21.06.2005.
|
||||||
|
Живу в Москве, учусь прогать, люблю курить dwm и иногда пишу разного рода дичь.
|
||||||
|
Самым интересным в своей жизни делюсь <a href="/blog">вот здесь</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
42
assets/css/common.css
Normal file
42
assets/css/common.css
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
body, html {
|
||||||
|
background-color: #151715;
|
||||||
|
color: white;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-container {
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-justify-content-center {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.5em;
|
||||||
|
padding-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-text {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: aqua;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: deepskyblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
color: #4c259a;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited:hover {
|
||||||
|
color: #613d9c;
|
||||||
|
}
|
||||||
2
src/lib.rs
Normal file
2
src/lib.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod yyyi_ru;
|
||||||
|
pub mod mtgott;
|
||||||
6
src/main.rs
Normal file
6
src/main.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use yyyi_ru::yyyi_ru::MAIN;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
MAIN().await
|
||||||
|
}
|
||||||
4
src/mtgott/mod.rs
Normal file
4
src/mtgott/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
pub fn proclaim_glad_tidings() {
|
||||||
|
println!("This project uses My Train Goes Off The Track!\n\
|
||||||
|
But I ain't writing this shit second time")
|
||||||
|
}
|
||||||
132
src/yyyi_ru/mod.rs
Normal file
132
src/yyyi_ru/mod.rs
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
use axum;
|
||||||
|
use std::io;
|
||||||
|
use std::fs;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use axum::http::HeaderValue;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use axum::http::header::CONTENT_TYPE;
|
||||||
|
use tera;
|
||||||
|
|
||||||
|
use crate::mtgott::{proclaim_glad_tidings};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct StaticAsset {
|
||||||
|
content_type: HeaderValue,
|
||||||
|
content: Vec<u8>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct AssetsCache {
|
||||||
|
page_index: StaticAsset,
|
||||||
|
page_blog: StaticAsset,
|
||||||
|
static_assets: HashMap<String, StaticAsset>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ExtensionContentTypeCorr{
|
||||||
|
extension: &'static str,
|
||||||
|
content_type: HeaderValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_static_html_page(p: &Path) -> io::Result<StaticAsset> {
|
||||||
|
Ok(StaticAsset {
|
||||||
|
content_type: HeaderValue::from_str("text/html").unwrap(),
|
||||||
|
content: fs::read(p)?
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AssetsCache {
|
||||||
|
fn load(p: &Path, need: &[ExtensionContentTypeCorr]) -> Result<AssetsCache, io::Error> {
|
||||||
|
if !p.is_dir() {
|
||||||
|
return Err(io::Error::from(io::ErrorKind::NotADirectory))
|
||||||
|
}
|
||||||
|
let mut st: HashMap<String, StaticAsset> = HashMap::new();
|
||||||
|
let mut td: Vec<String> = vec![String::new()];
|
||||||
|
while td.len() > 0 {
|
||||||
|
let dshp_dir: String = td.pop().unwrap();
|
||||||
|
let p_dir = p.join(dshp_dir.clone());
|
||||||
|
for entry in fs::read_dir(p_dir)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let dshp_child = if dshp_dir.len() > 0 {
|
||||||
|
format!("{dshp_dir}/{}", entry.file_name().to_str().unwrap())
|
||||||
|
} else {
|
||||||
|
String::from(entry.file_name().to_str().unwrap())
|
||||||
|
};
|
||||||
|
let p_child = p.join(dshp_child.clone());
|
||||||
|
if p_child.is_dir() {
|
||||||
|
td.push(dshp_child);
|
||||||
|
} else {
|
||||||
|
if let Some(ext) = need.iter().find(|ext| {dshp_child.ends_with(ext.extension)}) {
|
||||||
|
st.insert(dshp_child.clone(), StaticAsset {
|
||||||
|
content_type: ext.content_type.clone(),
|
||||||
|
content: fs::read(p.join(dshp_child))?
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(AssetsCache{
|
||||||
|
page_index: read_static_html_page(&p.join("HypertextPages/index.html"))?,
|
||||||
|
page_blog: read_static_html_page(&p.join("HypertextPages/blog.html"))?,
|
||||||
|
static_assets: st
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn page_index(
|
||||||
|
axum::extract::State(assets): axum::extract::State<Arc<AssetsCache>>
|
||||||
|
) -> impl axum::response::IntoResponse {
|
||||||
|
(
|
||||||
|
[(CONTENT_TYPE, assets.page_index.content_type.clone())],
|
||||||
|
assets.page_index.content.clone()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn static_assets(
|
||||||
|
axum::extract::Path(path): axum::extract::Path<String>,
|
||||||
|
axum::extract::State(assets): axum::extract::State<Arc<AssetsCache>>,
|
||||||
|
) -> Result<([(axum::http::HeaderName, axum::http::HeaderValue); 1], Vec<u8>), axum::http::StatusCode> {
|
||||||
|
if let Some(file) = assets.static_assets.get(&path) {
|
||||||
|
return Ok((
|
||||||
|
[(CONTENT_TYPE, file.content_type.clone())],
|
||||||
|
file.content.clone()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
Err(axum::http::StatusCode::NOT_FOUND)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async fn page_blog(
|
||||||
|
axum::extract::State(assets): axum::extract::State<Arc<AssetsCache>>
|
||||||
|
) -> impl axum::response::IntoResponse {
|
||||||
|
axum::response::Html(String::from_utf8(assets.page_blog.content.clone()).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn fallback_page() -> axum::http::StatusCode {
|
||||||
|
axum::http::StatusCode::NOT_FOUND
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn MAIN() {
|
||||||
|
let manifest_dir = env!("CARGO_MANIFEST_DIR");
|
||||||
|
println!("Cargo manifest dir: {manifest_dir}");
|
||||||
|
let static_assets_types: &[ExtensionContentTypeCorr] = &[
|
||||||
|
ExtensionContentTypeCorr{extension: "css", content_type: HeaderValue::from_str("text/css").unwrap()}
|
||||||
|
];
|
||||||
|
let assets = Arc::new(
|
||||||
|
AssetsCache::load(
|
||||||
|
&Path::new(manifest_dir).join("assets"),
|
||||||
|
static_assets_types).unwrap());
|
||||||
|
|
||||||
|
// build our application with a single route
|
||||||
|
let app = axum::Router::new()
|
||||||
|
.without_v07_checks()
|
||||||
|
.route("/", axum::routing::MethodRouter::new().get(page_index))
|
||||||
|
.route("/assets/{*path}", axum::routing::get(static_assets))
|
||||||
|
.route("/blog", axum::routing::get(page_blog))
|
||||||
|
.fallback(fallback_page).with_state(assets);
|
||||||
|
|
||||||
|
// run our app with hyper, listening globally on port 3000
|
||||||
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||||
|
axum::serve(listener, app).await.unwrap();
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user