#!/bin/bash readonly toolName="paperless-ngx" readonly toolUser="paperless" readonly toolDeps="python3 python3-pip python3-dev default-libmysqlclient-dev imagemagick fonts-liberation gnupg libpq-dev libmagic-dev mime-support libzbar0 poppler-utils redis-server" readonly toolDepsOcr="unpaper ghostscript icc-profiles-free qpdf liblept5 libxml2 pngquant zlib1g tesseract-ocr" readonly versionUrl="https://api.github.com/repos/paperless-ngx/paperless-ngx/releases/latest" versionNew= versionNow= downUrl= sq_paperlessDownLoc="/tmp/paperless_latest.tar.xz" sq_aptOpt= seq_config() { ## or to use sequencer api with global config file: if initSeqConfig "${seq_configName:?}" "${seq_configTemplate:?}" ; then sq_config=1 else # End if no configuration file exists dry || return 1 fi ## Apt cmdline option to suppress user interaction interactive || sq_aptOpt="-y" ## Disable error checks if external scripts are used ## e.g. error on unbound variables #disableErrorCheck ## Return of non zero value will abort the sequence return 0 } getVersions() { versionNew="${versionNew:-$(curl --silent "$versionUrl" | grep -Po '"tag_name": "v\K.*?(?=")')}" versionNow="${versionNow:-$(grep -Po '"Paperless-ngx",version:"\K.*?(?=")' 2>/dev/null < "${sc_paperlessDir}/static/frontend/de-DE/main.js")}" downUrl="${downUrl:-"https://github.com/paperless-ngx/paperless-ngx/releases/download/v${versionNew:?}/paperless-ngx-v${versionNew:?}.tar.xz"}" } step_1_info() { echo "Status of ${toolName}"; } step_1_alias() { echo "status"; } step_1() { getVersions info -n "${toolName} " if [[ -n "${versionNow}" ]] ; then color green info -d "version ${versionNow} installed" if [[ ! ${versionNow:-} == ${versionNew} ]] ; then info -a "Update available to version ${versionNew} from:" info -a "${downUrl}" fi else color yellow info -d "not installed" info -a "Version ${versionNew} available for installation from:" info -a "${downUrl}" fi } step_3_info() { echo "Manage ${toolName} services"; } step_3_options() { echo "[status|start|stop|restart]"; } step_3_alias() { echo "service"; } step_3() { shift local serviceCommand="is-active" case "${1:-"status"}" in start) serviceCommand="${1}" ;; stop) serviceCommand="${1}" ;; restart) serviceCommand="${1}" ;; status) serviceCommand="is-active" info -n " paperless-webserver: " exe systemctl "${serviceCommand:?}" paperless-webserver info -na " paperless-scheduler: " exe systemctl "${serviceCommand:?}" paperless-scheduler info -na " paperless-consumer: " exe systemctl "${serviceCommand:?}" paperless-consumer info -na "paperless-task-queue: " exe systemctl "${serviceCommand:?}" paperless-task-queue.service return 0 ;; "") ;; *) error "Unknown command ${1:-"-"}" return 1 ;; esac exe systemctl "${serviceCommand:?}" paperless-webserver exe systemctl "${serviceCommand:?}" paperless-scheduler exe systemctl "${serviceCommand:?}" paperless-consumer exe systemctl "${serviceCommand:?}" paperless-task-queue } step_10_info() { echo "Install python3"; } step_10_alias() { echo "install"; } step_10() { exe apt update exe apt install ${toolDeps} ${aptOpt:-} exe apt install ${toolDepsOcr} ${aptOpt:-} } step_11_info() { echo "Add system user"; } step_11() { if id "${toolUser}" >/dev/null 2>&1 ; then endReturn -o 1 "User ${toolUser} already exists" fi exe adduser "${toolUser}" --system --group --home "${sc_paperlessHome}" } step_12_info() { echo "Install/upgrade ${toolName}"; } step_12_alias() { echo "upgrade"; } step_12() { local toolUpgrade=0 getVersions if [[ ${versionNow:-} == ${versionNew} ]] ; then endReturn -o 1 "Latest version ${versionNow} already installed" else if [ -n "${versionNow:-}" ] ; then info "Upgrading $toolName from ${versionNow} to ${versionNew}" else info "Installing $toolName version ${versionNew}" fi fi exe wget ${downUrl} -q -O "${sq_paperlessDownLoc}" endReturn -o $? "Download failed" if [ -e "${sc_paperlessDir}" ] ; then if step backup --nostart; then info "Backup successful" else endReturn -o 1 "Backup failed." fi toolUpgrade=1 exe mv "${sc_paperlessDir}" "${sc_paperlessDir}_bu" fi exe tar -xf "${sq_paperlessDownLoc}" -C "${sc_paperlessHome}" exe chown -R "${toolUser}": "${sc_paperlessDir}" if ((toolUpgrade)) ; then info "Moving over ${toolName} and gunicorn configuration" addConf -c -f "${sc_paperlessDir}_bu/paperless.conf" "${sc_paperlessDir}/paperless.conf" saveReturn $? addConf -c -f "${sc_paperlessDir}_bu/gunicorn.conf.py" "${sc_paperlessDir}/gunicorn.conf.py" saveReturn $? endReturn "${toolName} configuration could not be transferred. ${sc_paperlessDir}_bu not deleted." exe rm -rf "${sc_paperlessDir}_bu" info "Starting post upgrade procedure" step postupgrade step service start die "Upgrade finished" fi } step_13_info() { echo "Install other dependcies"; } step_13_alias() { echo "requirements"; } step_13() { exe cd "${sc_paperlessHome}" exe sudo -Hu paperless pip3 install --upgrade pip exe sudo -Hu paperless pip3 install --requirement "${sc_paperlessDir}/requirements.txt" } step_14_info() { echo "Initialization"; } step_14() { exe install --owner="${toolUser}" --group="${toolUser}" -d "${sc_paperlessHome}/"{consume,data,media} exe cd "${sc_paperlessDir}/src" exe sudo -Hu paperless python3 manage.py migrate exe sudo -Hu paperless python3 manage.py createsuperuser } step_16_info() { echo "Post upgrade steps"; } step_16_alias() { echo "postupgrade"; } step_16() { step requirements exe cd "${sc_paperlessDir}/src" exe sudo -Hu paperless python3 manage.py migrate } step_18_info() { echo "Retag existing documents" echoinfo "OPTIONS" echoinfo " -c, --correspondent" echoinfo " -T, --tags" echoinfo " -t, --document_type" echoinfo " -i, --inbox-only" echoinfo " --use-first" echoinfo " -f, --overwrite" } step_18_options() { echo "[OPTIONS]"; } step_18_alias() { echo "retag"; } step_18() { shift exe cd "${sc_paperlessDir}/src" exe sudo -Hu paperless python3 manage.py document_retagger "$@" } step_20_info() { echo "Manage document search index" echoinfo " reindex - (default) create index from scratch" echoinfo " optimize - updates index to increase search speed and" echoinfo " ensures autocompletion" } step_20_options() { echo "[reindex|optimize]"; } step_20_alias() { echo "reindex"; } step_20() { shift local command="${1:-"reindex"}" case "${1:-}" in reindex) ;; optimize) ;; "") ;; *) fatal "Unkown argument ${1}" ;; esac exe cd "${sc_paperlessDir}/src" exe sudo -Hu paperless python3 manage.py document_index "${command}" } step_22_info() { echo "Rename (apply storage paths) to existing documents" echoinfo "Be aware that this command moves files on the file system." echoinfo "Consider creating a backup before execution." } step_22_alias() { echo "rename"; } step_22() { exe cd "${sc_paperlessDir}/src" exe sudo -Hu paperless python3 manage.py document_renamer } step_30_info() { echo "Backup ${toolName}"; } step_30_options() { echo "[--nostart]"; } step_30_alias() { echo "backup"; } step_30() { shift info "Doing backup..." step service stop exe cd "$(dirname -- "${sc_paperlessHome}")" exe tar czf "${sc_paperlessBackupDir:-"${HOME}/backup"}/paperless_backup_$(date +%Y%m%d-%H%M%S).tar.gz" \ "$(basename -- "${sc_paperlessHome}")" #--exclude="$(basename -- "${sc_paperlessHome}")/.local" \ #--exclude="$(basename -- "${sc_paperlessHome}")/.cache" \ if [[ ${1:-} == "--nostart" ]] ; then info "Not starting ${toolName} services after backup" else step service start fi } step_100_info() { echo "Notes"; } step_100_alias() { echo "notes"; } step_100() { color green cat < # Nginx proxy --- server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name mydomain.com; access_log off; #/var/log/nginx/paperless.log; error_log /var/log/nginx/paperless_error.log; include /etc/nginx/ssl.conf; error_page 497 https://\$host:\$server_port\$request_uri; fastcgi_read_timeout 300s; proxy_read_timeout 65s; client_max_body_size 20M; location / { proxy_pass http://10.0.0.10/; # These configuration options are required for WebSockets to work. proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; proxy_set_header Host \$http_host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; } } --- EOF_NOTES color none } readonly sqr_minVersion=16 . sequencer.sh