Compare commits

..

No commits in common. "c8ce4db2a2234beecadd8f6ce2f32e6f74deb697" and "8542ea2ef7d1cf989aa65b420f914f42334e1a0a" have entirely different histories.

6 changed files with 111 additions and 237 deletions

23
flake.lock generated
View file

@ -16,30 +16,9 @@
"type": "github" "type": "github"
} }
}, },
"pyproject-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1758265079,
"narHash": "sha256-amLaLNwKSZPShQHzfgmc/9o76dU8xzN0743dWgvYlr8=",
"owner": "nix-community",
"repo": "pyproject.nix",
"rev": "02e9418fd4af638447dca4b17b1280da95527fc9",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "pyproject.nix",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs"
"pyproject-nix": "pyproject-nix"
} }
} }
}, },

View file

@ -1,85 +1,59 @@
{ {
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
pyproject-nix = {
url = "github:nix-community/pyproject.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = { outputs = {
self, self,
nixpkgs, nixpkgs,
...
} @ inputs: let } @ inputs: let
system = "x86_64-linux"; system = "x86_64-linux";
pkgs = import nixpkgs { pkgs = import nixpkgs {
inherit system; inherit system;
config.allowUnfree = true; config.allowUnfree = true;
}; };
python = pkgs.python3; in {
serverProject = inputs.pyproject-nix.lib.project.loadPyproject { devShells.${system}.default = pkgs.mkShell {
projectRoot = ./.; packages = with pkgs; [
}; python313
python313Packages.flask
python313Packages.waitress
];
# Packages shellHook = ''
script = pkgs.writeShellApplication { python --version
name = "scanbuddy"; exec zsh
'';
};
packages.${system} = let
scanbuddy = pkgs.writeShellApplication {
name = "scanbuddy-script";
runtimeInputs = with pkgs; [sane-backends brscan5 ghostscript]; runtimeInputs = with pkgs; [sane-backends brscan5 ghostscript];
text = builtins.readFile ./scanbuddy.bash; text = builtins.readFile ./scanbuddy.bash;
}; };
wrapper = pkgs.writeShellApplication {
name = "scanbuddy-wrapper";
# Returns an attribute set that can be passed to `buildPythonPackage`. text =
attrs = serverProject.renderers.buildPythonPackage {inherit python;}; /*
server = python.pkgs.buildPythonPackage (attrs bash
// { */
env.CUSTOM_ENVVAR = "foobar"; ''
}); #!/usr/bin/env bash
readarray -d '_' args < <(printf "%s" "$1")
scanbuddy-pkg = pkgs.symlinkJoin { scanbuddy "''${args[@]}"
'';
};
package = pkgs.symlinkJoin {
name = "scanbuddy"; name = "scanbuddy";
paths = [script server]; paths = [scanbuddy wrapper];
}; };
in { in {
# devShells.${system}.default = pkgs.mkShell { default = package;
# packages = with pkgs; [ inherit scanbuddy;
# python313 inherit wrapper;
# python313Packages.flask
# python313Packages.waitress
# ];
#
# shellHook = ''
# python --version
# exec zsh
# '';
# };
packages.${system} = {
default = scanbuddy-pkg;
inherit script;
inherit server;
};
nixosModules.default = {
config,
pkgs,
lib,
...
}: {
options = {
service.scanbuddy = lib.mkEnableOption "Enable the scanbuddy server";
};
config = {
systemd.services.scanbuddy = lib.mkIf config.service.scanbuddy {
description = "The scanbuddy webservice";
wantedBy = ["multi-user.target"];
serviceConfig = {
ExecStart = "${scanbuddy-pkg}/bin/scanbuddy-server";
Path = ["${scanbuddy-pkg}/bin"];
WorkingDirectory = "/var/lib/scanbuddy";
};
};
};
}; };
}; };
} }

View file

@ -1,15 +0,0 @@
[project]
name = "scanbuddy-server"
version = "0.1.0"
description = "A REST server for the scanbuddy shell-script"
# define any Python dependencies
dependencies = [
"flask>3",
"waitress"
]
# define the CLI executable
# Here, we define the entry point to be the 'main()' function in the module 'app/main.py'
[project.scripts]
scanbuddy-server = "server.server:main"

View file

@ -13,6 +13,7 @@ sides=$simplex_source
mode='c' mode='c'
resolution='300' resolution='300'
current_page=$(find "$PWD" -name "out*.pdf" | sort | tail -n 1); current_page=$(find "$PWD" -name "out*.pdf" | sort | tail -n 1);
read -r current_pageno <<<"${current_page//[^0-9]/ }" read -r current_pageno <<<"${current_page//[^0-9]/ }"
current_pageno=${current_pageno:-0} current_pageno=${current_pageno:-0}
@ -76,12 +77,19 @@ scan() {
-x 210 -y 297 # A4 -x 210 -y 297 # A4
} }
clean() { if [ "$#" -lt 1 ]; then
echo "Cleaning up..." echo "You need an argument!"
rm -rfv "$PWD/out*.pdf" exit 1
} fi
dispatch() { case "$1" in
scan)
scan "${@:2}"
;;
unscan)
rm "$last_out_file"
;;
dispatch)
readarray -d '' out_files < <(find . -regextype posix-awk -regex "\./out[0-9]+\.pdf" -print0 | sort -Vz) readarray -d '' out_files < <(find . -regextype posix-awk -regex "\./out[0-9]+\.pdf" -print0 | sort -Vz)
combined_file=$(mktemp --suff="_scanbuddy.pdf") combined_file=$(mktemp --suff="_scanbuddy.pdf")
gs -q -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE="$combined_file" -dBATCH "${out_files[@]}" gs -q -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE="$combined_file" -dBATCH "${out_files[@]}"
@ -99,29 +107,8 @@ dispatch() {
else else
printf "Paperless consumption job: %s\n" "$PAPERLESS_STATUS" printf "Paperless consumption job: %s\n" "$PAPERLESS_STATUS"
fi fi
clean
}
if [ "$#" -lt 1 ]; then
echo "You need an argument!"
exit 1
fi
case "$1" in
scan)
scan "${@:2}"
;;
unscan)
rm "$last_out_file"
;;
dispatch)
dispatch "${@:2}"
;;
clean)
clean
;; ;;
*) *)
echo "Usage: scanbuddy scan|unscan|dispatch|clean" echo "Usage: scanbuddy"
;; ;;
esac esac

52
server.py Executable file
View file

@ -0,0 +1,52 @@
#!/usr/bin/env python3
# Run this stuff with `waitress-serve --port=5000 --call server:create_app`
import os
import subprocess
from flask import Flask, request
app = Flask(__name__)
@app.route("/")
def hello_world():
return "Hello, World! Yoyoyo"
@app.route("/scan")
def scan():
command = ["bash", f"{os.getcwd()}/scanbuddy.bash", "scan"]
command += ["-d"] if (request.args.get("duplex", "n") == 'y') else []
result = subprocess.run(command, stdout=subprocess.PIPE, text=True)
output = result.stdout.strip()
print("Scanbuddy output: ")
print(output)
return output
# return f"Scanning {'duplex' if duplex == 'y' else ''}..."
@app.route("/dispatch")
def dispatch():
command = ["bash", f"{os.getcwd()}/scanbuddy.bash", "dispatch"]
user = request.args.get("user", "")
result = subprocess.run(command, stdout=subprocess.PIPE, text=True)
output = result.stdout.strip()
print("Scanbuddy output: ")
print(output)
return "Dispatching..."
@app.route("/unscan")
def unscan():
return "Unscanning..."
def create_app():
return app
if __name__=='__main__':
from waitress import serve
serve(app, host="0.0.0.0", port=8080)

View file

@ -1,103 +0,0 @@
#!/usr/bin/env python3
# Run this stuff with `waitress-serve --port=5000 --call server:create_app`
import os
import subprocess
from flask import Flask, request
app = Flask(__name__)
SCANBUDDY_COMMAND = ["bash", f"{os.getcwd()}/scanbuddy.bash"]
@app.route("/")
def hello_world():
return ("Scanbuddy server. Go to <ul>"
" <li><a href=\"scan\">scan</a></li>"
" <li><a href=\"unscan\">unscan</a></li>"
" <li><a href=\"dispatch\">dispatch</a></li>"
" <li><a href=\"clean\">clean</a></li>"
"</ul>")
@app.route("/scan")
def scan():
print("Scanning...")
command = SCANBUDDY_COMMAND + ["scan"]
duplex = request.args.get("duplex", "n") == 'y'
resolution = request.args.get("resolution", None)
if duplex:
print("Duplex: on")
command += ["-d"]
if resolution:
print(f"Res.: {int(resolution)}")
# turning the string to an int and back to a string should clean up the input
command += ["-r", f"{int(resolution)}"]
result = subprocess.run(command, stdout=subprocess.PIPE, text=True)
output = result.stdout.strip()
print("Scanbuddy output: ")
print(output)
return output
# return f"Scanning {'duplex' if duplex == 'y' else ''}..."
@app.route("/dispatch")
def dispatch():
print("Dispatching...")
command = SCANBUDDY_COMMAND + ["dispatch"]
# TODO: implement user
user = request.args.get("user", "")
result = subprocess.run(command, stdout=subprocess.PIPE, text=True)
output = result.stdout.strip()
print("Scanbuddy output: ")
print(output)
return output
@app.route("/unscan")
def unscan():
print("Unscanning...")
command = SCANBUDDY_COMMAND + ["unscan"]
result = subprocess.run(command, stdout=subprocess.PIPE, text=True)
output = result.stdout.strip()
print("Scanbuddy output: ")
print(output)
return output
@app.route("/clean")
def clean():
print("Cleaning...")
command = SCANBUDDY_COMMAND + ["clean"]
result = subprocess.run(command, stdout=subprocess.PIPE, text=True)
output = result.stdout.strip()
print("Scanbuddy output: ")
print(output)
return output
def create_app():
return app
def main():
from waitress import serve
print("Serving scanbuddy on port 5000")
serve(app, host="0.0.0.0", port=5000)
if __name__=='__main__':
main()