Dumb af systemctl thingy
This commit is contained in:
commit
7807eb0c42
7 changed files with 691 additions and 0 deletions
1
.envrc
Normal file
1
.envrc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
use flake . --impure
|
||||||
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "botloc"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
axum = { version = "0.7.5", features = ["multipart", "macros"] }
|
||||||
|
serde = { version = "1.0.203", features = ["derive"] }
|
||||||
|
serde_json = "1.0.118"
|
||||||
|
tokio = { version = "1.38.0", features = ["full"] }
|
||||||
|
tracing = "0.1.40"
|
||||||
|
tracing-subscriber = "0.3.18"
|
||||||
314
flake.lock
generated
Normal file
314
flake.lock
generated
Normal file
|
|
@ -0,0 +1,314 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"cargo-semver-checks": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"naersk": "naersk",
|
||||||
|
"nixpkgs": "nixpkgs_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1718446388,
|
||||||
|
"narHash": "sha256-/4a5CS5EdI+g1Y/nzOeAmI04olLDCk8SDhQbPqL82s4=",
|
||||||
|
"owner": "Maix0",
|
||||||
|
"repo": "cargo-semver-checks-flake",
|
||||||
|
"rev": "10641cbb61ecb2ec40c4847080a08c8d4ee8bec0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "Maix0",
|
||||||
|
"repo": "cargo-semver-checks-flake",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cargo-workspace": {
|
||||||
|
"inputs": {
|
||||||
|
"cargo-workspaces-git": "cargo-workspaces-git",
|
||||||
|
"flake-utils": "flake-utils_2",
|
||||||
|
"naersk": "naersk_2",
|
||||||
|
"nixpkgs": "nixpkgs_4"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1718446390,
|
||||||
|
"narHash": "sha256-YAgg27LQwK6BfOIut/U8zqDN87L0SxU9SRC98Bsp16w=",
|
||||||
|
"owner": "Maix0",
|
||||||
|
"repo": "cargo-ws-flake",
|
||||||
|
"rev": "bbb8a52d1a294549f81a52c226fa3c085e44e5af",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "Maix0",
|
||||||
|
"repo": "cargo-ws-flake",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cargo-workspaces-git": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1683825807,
|
||||||
|
"narHash": "sha256-WlJu8FLaTMzR5JCU5eASHfmJ3C4IdwlPZ6//m5xOb1k=",
|
||||||
|
"owner": "pksunkara",
|
||||||
|
"repo": "cargo-workspaces",
|
||||||
|
"rev": "8bf9c4ab519eeed45e83cbc64aa646431bddd899",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "pksunkara",
|
||||||
|
"ref": "v0.2.41",
|
||||||
|
"repo": "cargo-workspaces",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1710146030,
|
||||||
|
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils_2": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1710146030,
|
||||||
|
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils_3": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems_3"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1710146030,
|
||||||
|
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"naersk": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1717067539,
|
||||||
|
"narHash": "sha256-oIs5EF+6VpHJRvvpVWuqCYJMMVW/6h59aYUv9lABLtY=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "naersk",
|
||||||
|
"rev": "fa19d8c135e776dc97f4dcca08656a0eeb28d5c0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "naersk",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"naersk_2": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs_3"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1717067539,
|
||||||
|
"narHash": "sha256-oIs5EF+6VpHJRvvpVWuqCYJMMVW/6h59aYUv9lABLtY=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "naersk",
|
||||||
|
"rev": "fa19d8c135e776dc97f4dcca08656a0eeb28d5c0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "naersk",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 0,
|
||||||
|
"narHash": "sha256-yZKhxVIKd2lsbOqYd5iDoUIwsRZFqE87smE2Vzf6Ck0=",
|
||||||
|
"path": "/nix/store/5jgh89kgmrb687c254wxdac4cj5hqjw8-source",
|
||||||
|
"type": "path"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1718276985,
|
||||||
|
"narHash": "sha256-u1fA0DYQYdeG+5kDm1bOoGcHtX0rtC7qs2YA2N1X++I=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "3f84a279f1a6290ce154c5531378acc827836fbb",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 0,
|
||||||
|
"narHash": "sha256-yZKhxVIKd2lsbOqYd5iDoUIwsRZFqE87smE2Vzf6Ck0=",
|
||||||
|
"path": "/nix/store/5jgh89kgmrb687c254wxdac4cj5hqjw8-source",
|
||||||
|
"type": "path"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_4": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1718276985,
|
||||||
|
"narHash": "sha256-u1fA0DYQYdeG+5kDm1bOoGcHtX0rtC7qs2YA2N1X++I=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "3f84a279f1a6290ce154c5531378acc827836fbb",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_5": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1719223410,
|
||||||
|
"narHash": "sha256-jtIo8xR0Zp4SalIwmD+OdCwHF4l7OU6PD63UUK4ckt4=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "efb39c6052f3ce51587cf19733f5f4e5d515aa13",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_6": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1718428119,
|
||||||
|
"narHash": "sha256-WdWDpNaq6u1IPtxtYHHWpl5BmabtpmLnMAx0RdJ/vo8=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "e6cea36f83499eb4e9cd184c8a8e823296b50ad5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"cargo-semver-checks": "cargo-semver-checks",
|
||||||
|
"cargo-workspace": "cargo-workspace",
|
||||||
|
"flake-utils": "flake-utils_3",
|
||||||
|
"nixpkgs": "nixpkgs_5",
|
||||||
|
"rust-overlay": "rust-overlay"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-overlay": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs_6"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1719281921,
|
||||||
|
"narHash": "sha256-LIBMfhM9pMOlEvBI757GOK5l0R58SRi6YpwfYMbf4yc=",
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"rev": "b6032d3a404d8a52ecfc8571ff0c26dfbe221d07",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
99
flake.nix
Normal file
99
flake.nix
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
{
|
||||||
|
description = "A basic flake with a shell";
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
rust-overlay.url = "github:oxalica/rust-overlay";
|
||||||
|
cargo-workspace.url = "github:Maix0/cargo-ws-flake";
|
||||||
|
cargo-semver-checks.url = "github:Maix0/cargo-semver-checks-flake";
|
||||||
|
};
|
||||||
|
outputs = {
|
||||||
|
self,
|
||||||
|
nixpkgs,
|
||||||
|
flake-utils,
|
||||||
|
rust-overlay,
|
||||||
|
...
|
||||||
|
} @ inputs:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system: let
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
overlays = [(import rust-overlay)];
|
||||||
|
};
|
||||||
|
packageIf = name: packageDef:
|
||||||
|
if builtins.hasAttr name inputs
|
||||||
|
then [(packageDef inputs.${name})]
|
||||||
|
else [];
|
||||||
|
buildRustToolchain = toolchainDef:
|
||||||
|
if builtins.isString toolchainDef
|
||||||
|
then let
|
||||||
|
split = pkgs.lib.strings.splitString "/" toolchainDef;
|
||||||
|
toolchainType =
|
||||||
|
if (builtins.length split) > 3
|
||||||
|
then throw "You can only specify a single version using `{type}/{version}/{profile}`"
|
||||||
|
else if (builtins.length split) >= 1
|
||||||
|
then builtins.elemAt split 0
|
||||||
|
else throw "You must specify at least a toolchain version with this format `{type}/{version}/{profile}`";
|
||||||
|
toolchainVersion =
|
||||||
|
if (builtins.length split) > 3
|
||||||
|
then throw "You can only specify a single version using `{type}/{version}/{profile}`"
|
||||||
|
else if (builtins.length split) >= 2
|
||||||
|
then builtins.elemAt split 1
|
||||||
|
else "latest";
|
||||||
|
toolchainProfile =
|
||||||
|
if (builtins.length split) > 3
|
||||||
|
then throw "You can only specify a single version using `{type}/{version}/{profile}`"
|
||||||
|
else if (builtins.length split) >= 3
|
||||||
|
then builtins.elemAt split 2
|
||||||
|
else "default";
|
||||||
|
in
|
||||||
|
buildRustToolchain {
|
||||||
|
toolchain = toolchainType;
|
||||||
|
version = toolchainVersion;
|
||||||
|
profile = toolchainProfile;
|
||||||
|
}
|
||||||
|
else if builtins.isAttrs toolchainDef
|
||||||
|
then
|
||||||
|
if toolchainDef.toolchain == "stable"
|
||||||
|
then pkgs.rust-bin.stable.${toolchainDef.version}.${toolchainDef.profile}.override (builtins.removeAttrs toolchainDef ["toolchain" "version" "profile"])
|
||||||
|
else if toolchainDef.toolchain == "beta"
|
||||||
|
then pkgs.rust-bin.beta.${toolchainDef.version}.${toolchainDef.profile}.override (builtins.removeAttrs toolchainDef ["toolchain" "version" "profile"])
|
||||||
|
else if toolchainDef.toolchain == "nightly"
|
||||||
|
then
|
||||||
|
if toolchainDef.version == "latest"
|
||||||
|
then pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.${toolchainDef.profile}.override (builtins.removeAttrs toolchainDef ["toolchain" "version" "profile"]))
|
||||||
|
else pkgs.rust-bin.nightly.${toolchainDef.version}.${toolchainDef.profile}.override (builtins.removeAttrs toolchainDef ["toolchain" "version" "profile"])
|
||||||
|
else throw "toolchain version isn't valid (not 'stable' or 'beta' or 'nightly')"
|
||||||
|
else throw "toolchainDef isn't a string or an attr describing the toolchain";
|
||||||
|
in {
|
||||||
|
devShell = let
|
||||||
|
rust_dev = buildRustToolchain "stable/latest/default";
|
||||||
|
# {
|
||||||
|
# extensions = [];
|
||||||
|
# targets = ["x86_64-unknown-linux-gnu"];
|
||||||
|
# };
|
||||||
|
in
|
||||||
|
pkgs.mkShell {
|
||||||
|
packages = with pkgs;
|
||||||
|
[
|
||||||
|
rust_dev
|
||||||
|
mold
|
||||||
|
openssl
|
||||||
|
pkg-config
|
||||||
|
]
|
||||||
|
++ (packageIf "cargo-semver-checks" (p: p.packages.${system}.default))
|
||||||
|
++ (packageIf "cargo-workspace" (p: p.packages.${system}.default));
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
export RUST_STD="${rust_dev}/share/doc/rust/html/std/index.html"
|
||||||
|
|
||||||
|
if [ -z $CARGO_TARGET_DIR ] then
|
||||||
|
: "''${XDG_CACHE_HOME:="''$HOME/.cache"}"
|
||||||
|
local hash path
|
||||||
|
hash="$(sha1sum - <<< "$PWD" | head -c40)"
|
||||||
|
path="''${PWD//[^a-zA-Z0-9]/}"
|
||||||
|
export CARGO_TARGET_DIR="''${XDG_CACHE_HOME}/rust-targets/$hash-$path"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
206
src/main.rs
Normal file
206
src/main.rs
Normal file
|
|
@ -0,0 +1,206 @@
|
||||||
|
//! Run with
|
||||||
|
//!
|
||||||
|
//! ```not_rust
|
||||||
|
//! cargo run -p example-readme
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
use axum::{
|
||||||
|
http::StatusCode,
|
||||||
|
response::{Html, IntoResponse, Redirect},
|
||||||
|
routing::{get, post},
|
||||||
|
Json, Router,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
|
use tracing::{error, info};
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
// initialize tracing
|
||||||
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
|
// build our application with a route
|
||||||
|
let app = Router::new()
|
||||||
|
// `GET /` goes to `root`
|
||||||
|
.route("/", get(root))
|
||||||
|
.route("/status", get(status))
|
||||||
|
.route("/stop", get(stop))
|
||||||
|
.route("/start", get(start))
|
||||||
|
.route("/restart", get(restart))
|
||||||
|
.route("/config", get(get_config).post(post_config));
|
||||||
|
|
||||||
|
// run our app with hyper
|
||||||
|
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
tracing::debug!("listening on {}", listener.local_addr().unwrap());
|
||||||
|
axum::serve(listener, app).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// basic handler that responds with a static string
|
||||||
|
async fn root() -> Html<&'static str> {
|
||||||
|
Html(
|
||||||
|
r#"
|
||||||
|
<a href="/restart">restart</a><br>
|
||||||
|
<a href="/stop">stop</a><br>
|
||||||
|
<a href="/start">start</a><br>
|
||||||
|
<a href="/status">status</a><br>
|
||||||
|
<a href="/config">config</a><br>
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn restart() -> Redirect {
|
||||||
|
info!("Requested to restart the bot");
|
||||||
|
tokio::spawn(async {
|
||||||
|
tokio::process::Command::new("systemctl")
|
||||||
|
.args(["--user", "restart", "botloc.service"])
|
||||||
|
.spawn()
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
Redirect::to("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn start() -> Redirect {
|
||||||
|
info!("Requested to start the bot");
|
||||||
|
tokio::spawn(async {
|
||||||
|
tokio::process::Command::new("systemctl")
|
||||||
|
.args(["--user", "start", "botloc.service"])
|
||||||
|
.spawn()
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
Redirect::to("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn stop() -> Redirect {
|
||||||
|
info!("Requested to stop the bot");
|
||||||
|
tokio::spawn(async {
|
||||||
|
tokio::process::Command::new("systemctl")
|
||||||
|
.args(["--user", "stop", "botloc.service"])
|
||||||
|
.spawn()
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
Redirect::to("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct BotConfig {
|
||||||
|
piscine: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_config() -> Result<Json<BotConfig>, (StatusCode, String)> {
|
||||||
|
info!("Requested config");
|
||||||
|
let Ok(mut file) = tokio::fs::File::open(std::env::var("CONFIG_PATH").map_err(|e| {
|
||||||
|
error!("Failed to open config file: {e}");
|
||||||
|
(
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"please set env CONFIG_PATH".to_string(),
|
||||||
|
)
|
||||||
|
})?)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
error!("Failed to open config file: {e}");
|
||||||
|
e
|
||||||
|
}) else {
|
||||||
|
return Err((
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!(
|
||||||
|
"failed to open config file: {}",
|
||||||
|
std::env::var("CONFIG_PATH").unwrap()
|
||||||
|
),
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut s = String::new();
|
||||||
|
if file
|
||||||
|
.read_to_string(&mut s)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
error!("Failed to open config file: {e}");
|
||||||
|
e
|
||||||
|
})
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
return Err((
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!(
|
||||||
|
"Failed to read config file at {}",
|
||||||
|
std::env::var("CONFIG_PATH").unwrap()
|
||||||
|
),
|
||||||
|
));
|
||||||
|
};
|
||||||
|
let Ok(val) = serde_json::from_str::<BotConfig>(&s).map_err(|e| {
|
||||||
|
error!("Failed to open config file: {e}");
|
||||||
|
e
|
||||||
|
}) else {
|
||||||
|
return Err((
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!(
|
||||||
|
"Failed to read config file as json at {}",
|
||||||
|
std::env::var("CONFIG_PATH").unwrap()
|
||||||
|
),
|
||||||
|
));
|
||||||
|
};
|
||||||
|
Ok(Json(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn post_config(Json(body): Json<BotConfig>) -> (StatusCode, String) {
|
||||||
|
info!("Posted config");
|
||||||
|
let Ok(mut file) = tokio::fs::File::open(
|
||||||
|
match std::env::var("CONFIG_PATH").map_err(|e| {
|
||||||
|
error!("Unset env {e}");
|
||||||
|
(
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"please set env CONFIG_PATH".to_string(),
|
||||||
|
)
|
||||||
|
}) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => return e,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
error!("Failed to open config file: {e}");
|
||||||
|
e
|
||||||
|
}) else {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!(
|
||||||
|
"failed to open config file: {}",
|
||||||
|
std::env::var("CONFIG_PATH").unwrap()
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
match serde_json::to_string_pretty(&body) {
|
||||||
|
Err(e) => {
|
||||||
|
error!("Failed to convert to json {e}");
|
||||||
|
return (StatusCode::OK, "Done".to_string());
|
||||||
|
}
|
||||||
|
Ok(s) => match file.write(s.as_bytes()).await {
|
||||||
|
Err(e) => error!("Got an error when writing file: {e}"),
|
||||||
|
Ok(_) => (),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
(StatusCode::OK, "Done".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn status() -> Result<String, StatusCode> {
|
||||||
|
info!("Requested status");
|
||||||
|
let mut output = tokio::process::Command::new("systemctl")
|
||||||
|
.args(["--user", "status", "botloc.service"])
|
||||||
|
.output()
|
||||||
|
.await
|
||||||
|
// let mut output = child.wait_with_output().await
|
||||||
|
.map_err(|e| {
|
||||||
|
error!("Error with systemctl status {e}");
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})?;
|
||||||
|
output.stdout.push(b'\n');
|
||||||
|
output.stdout.append(&mut output.stderr);
|
||||||
|
String::from_utf8(output.stdout).map_err(|e| {
|
||||||
|
error!("Error with systemctl status output {e}");
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
|
})
|
||||||
|
}
|
||||||
58
src/utils/memory_db_util.rs
Normal file
58
src/utils/memory_db_util.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
thread::spawn,
|
||||||
|
time::SystemTime,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct AxumState {
|
||||||
|
db: Arc<Mutex<HashMap<String, ItemOauthAxum>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct ItemOauthAxum {
|
||||||
|
pub verifier: String,
|
||||||
|
pub created_at: SystemTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AxumState {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let db: Arc<Mutex<HashMap<String, ItemOauthAxum>>> = Arc::new(Mutex::new(HashMap::new()));
|
||||||
|
let db_binding = Arc::clone(&db);
|
||||||
|
spawn(move || loop {
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(10));
|
||||||
|
let mut db = db_binding.lock().unwrap();
|
||||||
|
let now = SystemTime::now();
|
||||||
|
db.retain(|_, item| now.duration_since(item.created_at).unwrap().as_secs() < 900);
|
||||||
|
});
|
||||||
|
AxumState {
|
||||||
|
db: Arc::clone(&db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, key: String) -> Option<String> {
|
||||||
|
let db = self.db.lock().unwrap();
|
||||||
|
if let Some(item) = db.get(&key) {
|
||||||
|
Some(item.verifier.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&self, key: String, value: String) {
|
||||||
|
let mut db = self.db.lock().unwrap();
|
||||||
|
db.insert(
|
||||||
|
key,
|
||||||
|
ItemOauthAxum {
|
||||||
|
verifier: value,
|
||||||
|
created_at: SystemTime::now(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_all_items(&self) -> Vec<ItemOauthAxum> {
|
||||||
|
let db = self.db.lock().unwrap();
|
||||||
|
db.values().cloned().collect::<Vec<ItemOauthAxum>>()
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/utils/mod.rs
Normal file
1
src/utils/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod memory_db_utils;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue