Merge branch 'main' of git.n2.pm:NotNite/u
This commit is contained in:
commit
4add9bcc8d
7 changed files with 383 additions and 8 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -228,6 +228,9 @@ name = "either"
|
|||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
|
@ -1087,6 +1090,7 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
"sqlformat",
|
||||
|
@ -1107,9 +1111,12 @@ dependencies = [
|
|||
"dotenvy",
|
||||
"either",
|
||||
"heck",
|
||||
"hex",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"sqlx-core",
|
||||
"sqlx-rt",
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
[package]
|
||||
name = "u"
|
||||
description = "blazingly-fast super-concurrent webscale file server"
|
||||
authors = ["NotNite <hi@notnite.com>"]
|
||||
license = "MIT"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.69"
|
||||
async-trait = "0.1.65"
|
||||
|
@ -14,7 +15,7 @@ hyper = "0.14.24"
|
|||
mime_guess = "2.0.4"
|
||||
nanoid = "0.4.0"
|
||||
serde = { version = "1.0.152", features = ["derive"] }
|
||||
sqlx = { version = "0.6.2", features = ["sqlite", "runtime-tokio-rustls"] }
|
||||
sqlx = { version = "0.6.2", features = ["sqlite", "runtime-tokio-rustls", "offline"] }
|
||||
tokio = { version = "1.26.0", features = ["full"] }
|
||||
tokio-stream = { version = "0.1.12", features = ["net"] }
|
||||
tower = "0.4.13"
|
||||
|
|
|
@ -35,7 +35,7 @@ requirements:
|
|||
|
||||
```sh
|
||||
export U_API_KEY="..."
|
||||
export U_HOST="https://.../"
|
||||
export U_HOST="https://..."
|
||||
export U_REVOCATION_KEY_PATH="$HOME/.u_revocation_keys"
|
||||
|
||||
./upload.sh /path/to/file
|
||||
|
|
141
flake.lock
Normal file
141
flake.lock
Normal file
|
@ -0,0 +1,141 @@
|
|||
{
|
||||
"nodes": {
|
||||
"crane": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"rust-overlay": "rust-overlay"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1681680516,
|
||||
"narHash": "sha256-EB8Adaeg4zgcYDJn9sR6UMjN/OHdIiMMK19+3LmmXQY=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "54b63c8eae4c50172cb50b612946ff1d2bc1c75c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1673956053,
|
||||
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1678901627,
|
||||
"narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1681202837,
|
||||
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1682566018,
|
||||
"narHash": "sha256-HPzPRFiy2o/7k7mtnwfM1E6NVZHiFbPdmYCMoIpkHO4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "8e3b64db39f2aaa14b35ee5376bd6a2e707cadc2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"crane": "crane",
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"crane",
|
||||
"flake-utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"crane",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1680488274,
|
||||
"narHash": "sha256-0vYMrZDdokVmPQQXtFpnqA2wEgCCUXf5a3dDuDVshn0=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "7ec2ff598a172c6e8584457167575b3a1a5d80d8",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
129
flake.nix
Normal file
129
flake.nix
Normal file
|
@ -0,0 +1,129 @@
|
|||
{
|
||||
description = "blazingly-fast super-concurrent webscale file server";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
crane.url = "github:ipetkov/crane";
|
||||
crane.inputs.nixpkgs.follows = "nixpkgs";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, crane, flake-utils }:
|
||||
let
|
||||
description = "blazingly-fast super-concurrent webscale file server";
|
||||
src = ./.;
|
||||
packages = flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages."${system}";
|
||||
craneLib = crane.lib.${system};
|
||||
in rec {
|
||||
packages.u = craneLib.buildPackage {
|
||||
pname = "u";
|
||||
version = "0.1.0";
|
||||
# Don't use cleanCargoSource here, as it removes sqlx-data.json
|
||||
src = src;
|
||||
doCheck = false;
|
||||
};
|
||||
|
||||
apps.u = flake-utils.lib.mkApp {
|
||||
name = "u";
|
||||
drv = packages.u;
|
||||
};
|
||||
|
||||
packages.u-upload = pkgs.stdenv.mkDerivation rec {
|
||||
name = "u-upload";
|
||||
src =
|
||||
(pkgs.writeScriptBin "u-upload" (builtins.readFile ./upload.sh));
|
||||
|
||||
buildInputs = with pkgs; [ curl jq xclip ];
|
||||
nativeBuildInputs = with pkgs; [ makeWrapper ];
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp bin/u-upload $out/bin
|
||||
wrapProgram $out/bin/u-upload \
|
||||
--prefix PATH : ${pkgs.lib.makeBinPath buildInputs}
|
||||
'';
|
||||
};
|
||||
|
||||
devShell = pkgs.mkShell {
|
||||
inputsFrom = [ packages.u ];
|
||||
nativeBuildInputs = with pkgs; [
|
||||
rustc
|
||||
cargo
|
||||
rust-analyzer
|
||||
sqlx-cli
|
||||
packages.u-upload
|
||||
];
|
||||
};
|
||||
});
|
||||
in packages // {
|
||||
nixosModule = { config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.u;
|
||||
pkg = self.packages.${pkgs.system}.u;
|
||||
in {
|
||||
options.services.u = {
|
||||
enable = mkEnableOption description;
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "u";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "u";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.int;
|
||||
default = 8075;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.u = {
|
||||
description = description;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
preStart = ''
|
||||
cat > /var/lib/u/.env <<EOF
|
||||
DATABASE_URL="sqlite:/var/lib/u/u.db"
|
||||
U_PORT="${toString cfg.port}"
|
||||
U_FILES_DIR="/var/lib/u/files"
|
||||
EOF
|
||||
|
||||
# Create and migrate the database
|
||||
${pkgs.sqlx-cli}/bin/sqlx database create
|
||||
${pkgs.sqlx-cli}/bin/sqlx migrate run --source "${src}/migrations"
|
||||
'';
|
||||
|
||||
script = "${pkg}/bin/u";
|
||||
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
Restart = "always";
|
||||
WorkingDirectory = "/var/lib/u";
|
||||
};
|
||||
};
|
||||
|
||||
users = {
|
||||
users = mkIf (cfg.user == "u") {
|
||||
u = {
|
||||
home = "/var/lib/u";
|
||||
createHome = true;
|
||||
group = cfg.group;
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
|
||||
groups = mkIf (cfg.group == "u") { u = { }; };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
97
sqlx-data.json
Normal file
97
sqlx-data.json
Normal file
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
"db": "SQLite",
|
||||
"311dd7c05c12408abfbe7dab000687defe924e52d2ca2ed3c7d95bc4a2db039c": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "insert into api_keys (key, admin) values ($1, false)"
|
||||
},
|
||||
"695d9690323bef0cba686448a5053968ebbb5720a7ca5b62a7f4538c972424d2": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "insert into api_keys (key, admin) values ($1, true)"
|
||||
},
|
||||
"8d43fd96f18e00d562d44d710cc0f5bb2ab40f724d5cbcfcbd960ba9450f0a2d": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "admin",
|
||||
"ordinal": 0,
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
}
|
||||
},
|
||||
"query": "select admin from api_keys where admin = true"
|
||||
},
|
||||
"906d2325e07efbaac3e84fd07994afc0b8720fb34baecb314f7e2123a83961dc": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "admin",
|
||||
"ordinal": 0,
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "select admin from api_keys where key = $1"
|
||||
},
|
||||
"c0a48d1ace5682569cfd52d74396193c6b34e463d1a1dfe1e6027f6f94f7befa": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
}
|
||||
},
|
||||
"query": "insert into files (id, revocation_key) values ($1, $2)"
|
||||
},
|
||||
"c450bea1caa31e3fc498d3eeadc25fa27d90ad83be87e89e336f56cdb7adb628": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "revocation_key",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "select revocation_key from files where id = $1"
|
||||
},
|
||||
"d0982a4445b0d5dceb424bfabdc21a88ff2c85042590e1cccd789a4cd7bc735c": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "delete from files where id = $1"
|
||||
}
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
#!/usr/bin/env sh
|
||||
set -eux
|
||||
set -eu
|
||||
|
||||
path=$1
|
||||
extension=$(echo "$path" | cut -d'.' -f2)
|
||||
|
||||
data=$(curl -F file=@$path -H "Authorization: $U_API_KEY" "$U_HOST/api/upload")
|
||||
data=$(curl -F file=@"$path" -H "Authorization: $U_API_KEY" "$U_HOST/api/upload")
|
||||
image_id=$(echo "$data" | jq -r .id)
|
||||
|
||||
image_revocation_key=$(echo "$data" | jq -r .revocation_key)
|
||||
echo "$image_id $image_revocation_key" >> $U_REVOCATION_KEY_PATH
|
||||
echo "$image_id $image_revocation_key" >> "$U_REVOCATION_KEY_PATH"
|
||||
|
||||
image_url="https://u.n2.pm/i/$image_id.$extension"
|
||||
image_url="$U_HOST/i/$image_id.$extension"
|
||||
echo "$image_url"
|
||||
echo "$image_url" | xclip -selection clipboard
|
||||
|
|
Loading…
Reference in a new issue