feat: add rss feed and remove rev feature
This commit is contained in:
parent
3937d8fd75
commit
5356e2dbb4
8 changed files with 268 additions and 13 deletions
180
api/Cargo.lock
generated
180
api/Cargo.lock
generated
|
|
@ -20,6 +20,15 @@ version = "0.2.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.102"
|
version = "1.0.102"
|
||||||
|
|
@ -41,6 +50,12 @@ version = "1.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum"
|
name = "axum"
|
||||||
version = "0.8.8"
|
version = "0.8.8"
|
||||||
|
|
@ -105,6 +120,12 @@ version = "2.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
|
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.20.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.11.1"
|
version = "1.11.1"
|
||||||
|
|
@ -127,6 +148,17 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
|
||||||
|
dependencies = [
|
||||||
|
"iana-time-zone",
|
||||||
|
"num-traits",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chumsky"
|
name = "chumsky"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
|
|
@ -436,6 +468,30 @@ dependencies = [
|
||||||
"tower-service",
|
"tower-service",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.65"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_collections"
|
name = "icu_collections"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
|
|
@ -568,6 +624,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
"base64",
|
"base64",
|
||||||
|
"chrono",
|
||||||
"lettre",
|
"lettre",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -576,6 +633,16 @@ dependencies = [
|
||||||
"tower-http",
|
"tower-http",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.91"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leb128fmt"
|
name = "leb128fmt"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
@ -706,6 +773,15 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.37.3"
|
version = "0.37.3"
|
||||||
|
|
@ -907,6 +983,12 @@ dependencies = [
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.23"
|
version = "1.0.23"
|
||||||
|
|
@ -1287,6 +1369,51 @@ dependencies = [
|
||||||
"wit-bindgen",
|
"wit-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.114"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.114"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.114"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.114"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-encoder"
|
name = "wasm-encoder"
|
||||||
version = "0.244.0"
|
version = "0.244.0"
|
||||||
|
|
@ -1321,12 +1448,65 @@ dependencies = [
|
||||||
"semver",
|
"semver",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.62.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-link",
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.60.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.59.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-link"
|
name = "windows-link"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.59.0"
|
version = "0.59.0"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.8"
|
axum = "0.8"
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
|
chrono = { version = "0.4", default-features = false, features = ["clock"] }
|
||||||
lettre = "0.11"
|
lettre = "0.11"
|
||||||
rusqlite = { version = "0.32", features = ["bundled"] }
|
rusqlite = { version = "0.32", features = ["bundled"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
|
use axum::http::header::CONTENT_TYPE;
|
||||||
use axum::http::{HeaderMap, StatusCode};
|
use axum::http::{HeaderMap, StatusCode};
|
||||||
|
use axum::response::IntoResponse;
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
|
|
@ -25,6 +28,22 @@ pub struct QuestionStats {
|
||||||
answered: i64,
|
answered: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SITE_URL: &str = "https://jetpham.com";
|
||||||
|
|
||||||
|
fn xml_escape(text: &str) -> String {
|
||||||
|
text.replace('&', "&")
|
||||||
|
.replace('<', "<")
|
||||||
|
.replace('>', ">")
|
||||||
|
.replace('"', """)
|
||||||
|
.replace('\'', "'")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rss_pub_date(timestamp: &str) -> String {
|
||||||
|
DateTime::parse_from_rfc3339(timestamp)
|
||||||
|
.map(|dt| dt.to_rfc2822())
|
||||||
|
.unwrap_or_else(|_| Utc::now().to_rfc2822())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_questions(
|
pub async fn get_questions(
|
||||||
State(state): State<Arc<AppState>>,
|
State(state): State<Arc<AppState>>,
|
||||||
) -> Result<Json<Vec<Question>>, StatusCode> {
|
) -> Result<Json<Vec<Question>>, StatusCode> {
|
||||||
|
|
@ -80,6 +99,63 @@ pub async fn get_question_stats(
|
||||||
Ok(Json(QuestionStats { asked, answered }))
|
Ok(Json(QuestionStats { asked, answered }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_question_rss(
|
||||||
|
State(state): State<Arc<AppState>>,
|
||||||
|
) -> Result<impl IntoResponse, StatusCode> {
|
||||||
|
let db = state
|
||||||
|
.db
|
||||||
|
.lock()
|
||||||
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||||
|
let mut stmt = db
|
||||||
|
.prepare(
|
||||||
|
"SELECT id, question, answer, created_at, answered_at \
|
||||||
|
FROM questions WHERE answer IS NOT NULL \
|
||||||
|
ORDER BY answered_at DESC",
|
||||||
|
)
|
||||||
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||||
|
|
||||||
|
let questions = stmt
|
||||||
|
.query_map([], |row| {
|
||||||
|
Ok(Question {
|
||||||
|
id: row.get(0)?,
|
||||||
|
question: row.get(1)?,
|
||||||
|
answer: row.get(2)?,
|
||||||
|
created_at: row.get(3)?,
|
||||||
|
answered_at: row.get(4)?,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
|
||||||
|
.collect::<Result<Vec<_>, _>>()
|
||||||
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||||
|
|
||||||
|
let items = questions
|
||||||
|
.into_iter()
|
||||||
|
.map(|question| {
|
||||||
|
let guid = format!("{SITE_URL}/qa#question-{}", question.id);
|
||||||
|
let description = format!(
|
||||||
|
"Question: {}\n\nAnswer: {}",
|
||||||
|
question.question, question.answer
|
||||||
|
);
|
||||||
|
|
||||||
|
format!(
|
||||||
|
"<item><title>{}</title><link>{}</link><guid>{}</guid><pubDate>{}</pubDate><description>{}</description></item>",
|
||||||
|
xml_escape(&question.question),
|
||||||
|
xml_escape(&guid),
|
||||||
|
xml_escape(&guid),
|
||||||
|
xml_escape(&rss_pub_date(&question.answered_at)),
|
||||||
|
xml_escape(&description),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("");
|
||||||
|
|
||||||
|
let xml = format!(
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><rss version=\"2.0\"><channel><title>Jet Pham Q+A</title><link>{SITE_URL}/qa</link><description>Answered questions from Jet Pham's site</description><language>en-us</language>{items}</channel></rss>"
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(([(CONTENT_TYPE, "application/rss+xml; charset=utf-8")], xml))
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct SubmitQuestion {
|
pub struct SubmitQuestion {
|
||||||
question: String,
|
question: String,
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ pub async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
get(handlers::get_questions).post(handlers::post_question),
|
get(handlers::get_questions).post(handlers::post_question),
|
||||||
)
|
)
|
||||||
.route("/api/questions/stats", get(handlers::get_question_stats))
|
.route("/api/questions/stats", get(handlers::get_question_stats))
|
||||||
|
.route("/qa/rss.xml", get(handlers::get_question_rss))
|
||||||
.route("/api/webhook", post(handlers::webhook))
|
.route("/api/webhook", post(handlers::webhook))
|
||||||
.layer(CorsLayer::permissive())
|
.layer(CorsLayer::permissive())
|
||||||
.with_state(state);
|
.with_state(state);
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,10 @@ in
|
||||||
reverse_proxy 127.0.0.1:3003
|
reverse_proxy 127.0.0.1:3003
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handle /qa/rss.xml {
|
||||||
|
reverse_proxy 127.0.0.1:3003
|
||||||
|
}
|
||||||
|
|
||||||
handle {
|
handle {
|
||||||
root * ${package}
|
root * ${package}
|
||||||
try_files {path} /index.html
|
try_files {path} /index.html
|
||||||
|
|
@ -161,6 +165,10 @@ in
|
||||||
reverse_proxy 127.0.0.1:3003
|
reverse_proxy 127.0.0.1:3003
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handle /qa/rss.xml {
|
||||||
|
reverse_proxy 127.0.0.1:3003
|
||||||
|
}
|
||||||
|
|
||||||
handle {
|
handle {
|
||||||
root * ${package}
|
root * ${package}
|
||||||
try_files {path} /index.html
|
try_files {path} /index.html
|
||||||
|
|
|
||||||
2
src/global.d.ts
vendored
2
src/global.d.ts
vendored
|
|
@ -1,7 +1,5 @@
|
||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
declare const __COMMIT_SHA__: string;
|
|
||||||
|
|
||||||
declare module "*.txt?raw" {
|
declare module "*.txt?raw" {
|
||||||
const content: string;
|
const content: string;
|
||||||
export default content;
|
export default content;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
const CLEARNET_HOST = "jetpham.com";
|
const CLEARNET_HOST = "jetpham.com";
|
||||||
const ONION_HOST =
|
const ONION_HOST =
|
||||||
"jet7tetd43snvjx3ng5jrhuwm2yhyp76tjtct5mtofg64apokcgq7fqd.onion";
|
"jet7tetd43snvjx3ng5jrhuwm2yhyp76tjtct5mtofg64apokcgq7fqd.onion";
|
||||||
const COMMIT_BASE_URL = "https://git.extremist.software/jet/website/commit/";
|
|
||||||
const REPO_URL = "https://git.extremist.software/jet/website";
|
const REPO_URL = "https://git.extremist.software/jet/website";
|
||||||
|
|
||||||
function isOnionHost(hostname: string): boolean {
|
function isOnionHost(hostname: string): boolean {
|
||||||
|
|
@ -26,17 +25,15 @@ export function renderFooter() {
|
||||||
const footer = document.getElementById("site-footer");
|
const footer = document.getElementById("site-footer");
|
||||||
if (!footer) return;
|
if (!footer) return;
|
||||||
|
|
||||||
const commitSha = __COMMIT_SHA__;
|
|
||||||
const shortSha = commitSha.slice(0, 7);
|
|
||||||
const mirror = getMirrorLink();
|
const mirror = getMirrorLink();
|
||||||
|
|
||||||
footer.innerHTML = `
|
footer.innerHTML = `
|
||||||
<div class="site-panel px-[2ch] py-[1ch]">
|
<div class="site-panel px-[2ch] py-[1ch]">
|
||||||
<div class="site-footer-inner">
|
<div class="site-footer-inner">
|
||||||
<span>rev <a href="${COMMIT_BASE_URL}${commitSha}">${shortSha}</a></span>
|
|
||||||
<span aria-hidden="true">|</span>
|
|
||||||
<a href="${REPO_URL}">src</a>
|
<a href="${REPO_URL}">src</a>
|
||||||
<span aria-hidden="true">|</span>
|
<span aria-hidden="true">|</span>
|
||||||
|
<a href="/qa/rss.xml" data-native-link>rss</a>
|
||||||
|
<span aria-hidden="true">|</span>
|
||||||
<a href="/pgp.txt" data-native-link>pgp</a>
|
<a href="/pgp.txt" data-native-link>pgp</a>
|
||||||
<span aria-hidden="true">|</span>
|
<span aria-hidden="true">|</span>
|
||||||
<a href="/ssh.txt" data-native-link>ssh</a>
|
<a href="/ssh.txt" data-native-link>ssh</a>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
import { execSync } from "node:child_process";
|
|
||||||
import tailwindcss from "@tailwindcss/vite";
|
import tailwindcss from "@tailwindcss/vite";
|
||||||
import wasm from "vite-plugin-wasm";
|
import wasm from "vite-plugin-wasm";
|
||||||
import topLevelAwait from "vite-plugin-top-level-await";
|
import topLevelAwait from "vite-plugin-top-level-await";
|
||||||
|
|
@ -7,12 +6,7 @@ import { viteSingleFile } from "vite-plugin-singlefile";
|
||||||
import ansi from "./vite-plugin-ansi";
|
import ansi from "./vite-plugin-ansi";
|
||||||
import markdown from "./vite-plugin-markdown";
|
import markdown from "./vite-plugin-markdown";
|
||||||
|
|
||||||
const commitSha = execSync("git rev-parse HEAD", { encoding: "utf8" }).trim();
|
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
define: {
|
|
||||||
__COMMIT_SHA__: JSON.stringify(commitSha),
|
|
||||||
},
|
|
||||||
plugins: [
|
plugins: [
|
||||||
ansi(),
|
ansi(),
|
||||||
markdown(),
|
markdown(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue