initial commit
This commit is contained in:
commit
433ea1c76b
5 changed files with 1156 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
/target
|
||||
/files
|
||||
/temp
|
||||
.env
|
||||
git_output_*
|
1018
Cargo.lock
generated
Normal file
1018
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
15
Cargo.toml
Normal file
15
Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "phone"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
axum = "0.7.2"
|
||||
chrono = "0.4.31"
|
||||
thiserror = "1.0.51"
|
||||
tokio = { version = "1.35.1", features = ["macros", "rt-multi-thread"] }
|
||||
tower = { version = "0.4.13", features = ["limit"] }
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = "0.3.18"
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# phone
|
||||
|
||||
webhooks and stuff for my phone
|
115
src/main.rs
Normal file
115
src/main.rs
Normal file
|
@ -0,0 +1,115 @@
|
|||
#![feature(let_chains)]
|
||||
|
||||
use std::{
|
||||
env,
|
||||
fs::OpenOptions,
|
||||
process::{Command, Stdio},
|
||||
time::SystemTime,
|
||||
};
|
||||
|
||||
use axum::{
|
||||
extract::State,
|
||||
http::{HeaderMap, StatusCode},
|
||||
response::{IntoResponse, Response},
|
||||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use chrono::{DateTime, Utc};
|
||||
use thiserror::Error;
|
||||
use tokio::net::TcpListener;
|
||||
use tower::limit::ConcurrencyLimitLayer;
|
||||
use tracing::error;
|
||||
|
||||
macro_rules! silly {
|
||||
($code:ident) => {
|
||||
(StatusCode::$code, StatusCode::$code.to_string())
|
||||
};
|
||||
}
|
||||
|
||||
struct Config {
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum AppError {
|
||||
#[error("Command failed to execute (exit code {0})")]
|
||||
CommandFailed(i32),
|
||||
#[error(transparent)]
|
||||
IoError(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
impl IntoResponse for AppError {
|
||||
fn into_response(self) -> Response {
|
||||
error!("{}", self);
|
||||
silly!(INTERNAL_SERVER_ERROR).into_response()
|
||||
}
|
||||
}
|
||||
|
||||
async fn update_website(
|
||||
State(secret): State<String>,
|
||||
headers: HeaderMap,
|
||||
) -> Result<StatusCode, AppError> {
|
||||
if let Some(secret_header) = headers.get("x-gitlab-token")
|
||||
&& *secret_header == secret
|
||||
{
|
||||
let now = SystemTime::now();
|
||||
let date: DateTime<Utc> = now.into();
|
||||
|
||||
let file_name = format!("git_output_{}", date);
|
||||
|
||||
let stdout_file = OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.open(&file_name)
|
||||
.unwrap();
|
||||
let stderr_file = OpenOptions::new().write(true).open(&file_name).unwrap();
|
||||
|
||||
#[allow(deprecated)]
|
||||
let result = Command::new("git")
|
||||
.current_dir(env::home_dir().unwrap().join("slonksite"))
|
||||
.arg("pull")
|
||||
.stdin(Stdio::null())
|
||||
.stdout(stdout_file)
|
||||
.stderr(stderr_file)
|
||||
.spawn()?
|
||||
.wait()
|
||||
.unwrap();
|
||||
|
||||
if result.success() {
|
||||
Ok(StatusCode::OK)
|
||||
} else {
|
||||
Err(AppError::CommandFailed(result.code().unwrap_or(1)))
|
||||
}
|
||||
} else {
|
||||
Ok(StatusCode::UNAUTHORIZED)
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let config = Config {
|
||||
host: env::var("HOST").unwrap_or("0.0.0.0".to_string()),
|
||||
port: env::var("PORT")
|
||||
.and_then(|port| Ok(port.parse::<u16>().unwrap()))
|
||||
.unwrap_or(5000),
|
||||
};
|
||||
|
||||
let app = Router::new()
|
||||
.route("/update_website", get(update_website))
|
||||
.layer(ConcurrencyLimitLayer::new(8))
|
||||
.with_state(env::var("SECRET").unwrap());
|
||||
|
||||
let address = (config.host, config.port);
|
||||
let listener = TcpListener::bind(address).await.unwrap();
|
||||
let local_addr = listener.local_addr().unwrap();
|
||||
tracing::info!(
|
||||
"listening on http://{}:{}",
|
||||
local_addr.ip(),
|
||||
local_addr.port()
|
||||
);
|
||||
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
Loading…
Reference in a new issue