diff --git a/flake.lock b/flake.lock index 0ed96fb..2155089 100644 --- a/flake.lock +++ b/flake.lock @@ -16,30 +16,9 @@ "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": { "inputs": { - "nixpkgs": "nixpkgs", - "pyproject-nix": "pyproject-nix" + "nixpkgs": "nixpkgs" } } }, diff --git a/flake.nix b/flake.nix index e10f4c4..ef747b6 100644 --- a/flake.nix +++ b/flake.nix @@ -1,85 +1,59 @@ { inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - pyproject-nix = { - url = "github:nix-community/pyproject.nix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; }; outputs = { self, nixpkgs, - ... } @ inputs: let system = "x86_64-linux"; pkgs = import nixpkgs { inherit system; config.allowUnfree = true; }; - python = pkgs.python3; - serverProject = inputs.pyproject-nix.lib.project.loadPyproject { - projectRoot = ./.; - }; - - # Packages - script = pkgs.writeShellApplication { - name = "scanbuddy"; - - runtimeInputs = with pkgs; [sane-backends brscan5 ghostscript]; - - text = builtins.readFile ./scanbuddy.bash; - }; - - # Returns an attribute set that can be passed to `buildPythonPackage`. - attrs = serverProject.renderers.buildPythonPackage {inherit python;}; - server = python.pkgs.buildPythonPackage (attrs - // { - env.CUSTOM_ENVVAR = "foobar"; - }); - - scanbuddy-pkg = pkgs.symlinkJoin { - name = "scanbuddy"; - paths = [script server]; - }; in { - # devShells.${system}.default = pkgs.mkShell { - # packages = with pkgs; [ - # python313 - # python313Packages.flask - # python313Packages.waitress - # ]; - # - # shellHook = '' - # python --version - # exec zsh - # ''; - # }; - packages.${system} = { - default = scanbuddy-pkg; - inherit script; - inherit server; - }; + devShells.${system}.default = pkgs.mkShell { + packages = with pkgs; [ + python313 + python313Packages.flask + python313Packages.waitress + ]; - nixosModules.default = { - config, - pkgs, - lib, - ... - }: { - options = { - service.scanbuddy = lib.mkEnableOption "Enable the scanbuddy server"; + shellHook = '' + python --version + exec zsh + ''; + }; + packages.${system} = let + scanbuddy = pkgs.writeShellApplication { + name = "scanbuddy-script"; + + runtimeInputs = with pkgs; [sane-backends brscan5 ghostscript]; + + text = builtins.readFile ./scanbuddy.bash; }; - 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"; - }; - }; + wrapper = pkgs.writeShellApplication { + name = "scanbuddy-wrapper"; + + text = + /* + bash + */ + '' + #!/usr/bin/env bash + readarray -d '_' args < <(printf "%s" "$1") + + scanbuddy "''${args[@]}" + ''; }; + package = pkgs.symlinkJoin { + name = "scanbuddy"; + paths = [scanbuddy wrapper]; + }; + in { + default = package; + inherit scanbuddy; + inherit wrapper; }; }; } diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 61e7598..0000000 --- a/pyproject.toml +++ /dev/null @@ -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" diff --git a/scanbuddy.bash b/scanbuddy.bash index 7e28472..0fd8e4c 100755 --- a/scanbuddy.bash +++ b/scanbuddy.bash @@ -13,6 +13,7 @@ sides=$simplex_source mode='c' resolution='300' + current_page=$(find "$PWD" -name "out*.pdf" | sort | tail -n 1); read -r current_pageno <<<"${current_page//[^0-9]/ }" current_pageno=${current_pageno:-0} @@ -76,33 +77,6 @@ scan() { -x 210 -y 297 # A4 } -clean() { - echo "Cleaning up..." - rm -rfv "$PWD/out*.pdf" -} - -dispatch() { - readarray -d '' out_files < <(find . -regextype posix-awk -regex "\./out[0-9]+\.pdf" -print0 | sort -Vz) - combined_file=$(mktemp --suff="_scanbuddy.pdf") - gs -q -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE="$combined_file" -dBATCH "${out_files[@]}" - echo "Merged pdf written to $combined_file" - - # send to paperless - PAPERLESS_STATUS=$(curl \ - -H "Authorization: Token $PAPERLESS_TOKEN" \ - -F document=@"$combined_file" \ - "$([ -v PAPERLESS_TAG ] && echo "-F tags=$PAPERLESS_TAG")" \ - "${PAPERLESS_URL}/api/documents/post_document/") || FAILED=1 - - if [ -v FAILED ]; then - printf "Paperless failed with message:\n%s" "$PAPERLESS_STATUS" - else - printf "Paperless consumption job: %s\n" "$PAPERLESS_STATUS" - fi - - clean -} - if [ "$#" -lt 1 ]; then echo "You need an argument!" exit 1 @@ -116,12 +90,25 @@ case "$1" in rm "$last_out_file" ;; dispatch) - dispatch "${@:2}" - ;; - clean) - clean + readarray -d '' out_files < <(find . -regextype posix-awk -regex "\./out[0-9]+\.pdf" -print0 | sort -Vz) + combined_file=$(mktemp --suff="_scanbuddy.pdf") + gs -q -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE="$combined_file" -dBATCH "${out_files[@]}" + echo "Merged pdf written to $combined_file" + + # send to paperless + PAPERLESS_STATUS=$(curl \ + -H "Authorization: Token $PAPERLESS_TOKEN" \ + -F document=@"$combined_file" \ + "$([ -v PAPERLESS_TAG ] && echo "-F tags=$PAPERLESS_TAG")" \ + "${PAPERLESS_URL}/api/documents/post_document/") || FAILED=1 + + if [ -v FAILED ]; then + printf "Paperless failed with message:\n%s" "$PAPERLESS_STATUS" + else + printf "Paperless consumption job: %s\n" "$PAPERLESS_STATUS" + fi ;; *) - echo "Usage: scanbuddy scan|unscan|dispatch|clean" + echo "Usage: scanbuddy" ;; esac diff --git a/server.py b/server.py new file mode 100755 index 0000000..ba2632b --- /dev/null +++ b/server.py @@ -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) diff --git a/server/server.py b/server/server.py deleted file mode 100755 index cb3b9b4..0000000 --- a/server/server.py +++ /dev/null @@ -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 ") - - -@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()