initial commit

This commit is contained in:
slonkazoid 2023-12-23 20:49:03 +03:00
commit 433ea1c76b
5 changed files with 1156 additions and 0 deletions

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
/target
/files
/temp
.env
git_output_*

1018
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

15
Cargo.toml Normal file
View 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
View file

@ -0,0 +1,3 @@
# phone
webhooks and stuff for my phone

115
src/main.rs Normal file
View 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();
}