diff --git a/docs/changelog.rst b/docs/changelog.rst
index c4443504f..d6ad73ce2 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -5,6 +5,16 @@
Changelog
*********
+paperless-ng 0.9.4
+##################
+
+* Front end: Clickable tags, correspondents and types allow quick filtering for related documents.
+* Front end: Saved views are now editable.
+* Front end: Preview documents directly in the browser.
+* Fixes:
+ * A severe error when trying to use post consume scripts.
+* The documentation now contains information about bare metal installs.
+
paperless-ng 0.9.3
##################
@@ -20,7 +30,7 @@ paperless-ng 0.9.3
aware of.
* Issue with the automatic classifier not working with only one tag.
* A couple issues with the search index being opened to eagerly.
-
+
* Added lots of tests for various parts of the application.
paperless-ng 0.9.2
diff --git a/docs/setup.rst b/docs/setup.rst
index 4e2826dd6..9853ce2f1 100644
--- a/docs/setup.rst
+++ b/docs/setup.rst
@@ -208,9 +208,147 @@ Docker Route
Bare Metal Route
================
-.. warning::
+Paperless runs on linux only. The following procedure has been tested on a minimal
+installation of Debian/Buster, which is the current stable release at the time of
+writing. Windows is not and will never be supported.
- TBD. User docker for now.
+1. Install dependencies. Paperless requires the following packages.
+
+ * ``python3`` 3.6, 3.7, 3.8 (3.9 is untested).
+ * ``python3-pip``, optionally ``pipenv`` for package installation
+ * ``python3-dev``
+
+ * ``imagemagick`` >= 6 for PDF conversion
+ * ``unpaper`` for cleaning documents before OCR
+ * ``ghostscript``
+ * ``optipng`` for optimising thumbnails
+ * ``tesseract-ocr`` >= 4.0.0 for OCR
+ * ``tesseract-ocr`` language packs (``tesseract-ocr-eng``, ``tesseract-ocr-deu``, etc)
+ * ``gnupg`` for handling encrypted documents
+ * ``libpoppler-cpp-dev`` for PDF to text conversion
+ * ``libmagic-dev`` for mime type detection
+ * ``libpq-dev`` for PostgreSQL
+
+ You will also need ``build-essential``, ``python3-setuptools`` and ``python3-wheel``
+ for installing some of the python dependencies. You can remove that
+ again after installation.
+
+2. Install ``redis`` >= 5.0 and configure it to start automatically.
+
+3. Optional. Install ``postgresql`` and configure a database, user and password for paperless. If you do not wish
+ to use PostgreSQL, SQLite is avialable as well.
+
+4. Get the release archive. If you pull the git repo as it is, you also have to compile the front end by yourself.
+ Extract the frontend to a place from where you wish to execute it, such as ``/opt/paperless``.
+
+5. Configure paperless. See :ref:`configuration` for details. Edit the included ``paperless.conf`` and adjust the
+ settings to your needs. Required settings for getting paperless running are:
+
+ * ``PAPERLESS_REDIS`` should point to your redis server, such as redis://localhost:6379.
+ * ``PAPERLESS_DBHOST`` should be the hostname on which your PostgreSQL server is running. Do not configure this
+ to use SQLite instead. Also configure port, database name, user and password as necessary.
+ * ``PAPERLESS_CONSUMPTION_DIR`` should point to a folder which paperless should watch for documents. You might
+ want to have this somewhere else. Likewise, ``PAPERLESS_DATA_DIR`` and ``PAPERLESS_MEDIA_ROOT`` define where
+ paperless stores its data. If you like, you can point both to the same directory.
+ * ``PAPERLESS_SECRET_KEY`` should be a random sequence of characters. It's used for authentication. Failure
+ to do so allows third parties to forge authentication credentials.
+
+ Many more adjustments can be made to paperless, especially the OCR part. The following options are recommended
+ for everyone:
+
+ * Set ``PAPERLESS_OCR_LANGUAGE`` to the language most of your documents are written in.
+ * Set ``PAPERLESS_TIME_ZONE`` to your local time zone.
+
+6. Setup permissions. Create a system users under which you wish to run paperless. Ensure that these directories exist
+ and that the user has write permissions to the following directories
+
+ * ``/opt/paperless/media``
+ * ``/opt/paperless/data``
+ * ``/opt/paperless/consume``
+
+ Adjust as necessary if you configured different folders.
+
+7. Install python requirements. Paperless comes with both Pipfiles for ``pipenv`` as well as with a ``requirements.txt``.
+ Both will install exactly the same requirements. It is up to you if you wish to use a virtual environment or not.
+
+8. Go to ``/opt/paperless/src``, and execute the following commands:
+
+ .. code:: bash
+
+ # This collects static files from paperless and django.
+ python3 manage.py collectstatic --clear --no-input
+
+ # This creates the database schema.
+ python3 manage.py migrate
+
+ # This creates your first paperless user
+ python3 manage.py createsuperuser
+
+9. Optional: Test that paperless is working by executing
+
+ .. code:: bash
+
+ # This collects static files from paperless and django.
+ python3 manage.py runserver
+
+ and pointing your browser to http://localhost:8000/.
+
+ .. warning::
+
+ This is a development server which should not be used in
+ production.
+
+ .. hint::
+
+ This will not start the consumer. Paperless does this in a
+ separate process.
+
+10. Setup systemd services to run paperless automatically. You may
+ use the service definition files included in the ``scripts`` folder
+ as a starting point.
+
+ Paperless needs the ``webserver`` script to run the webserver, the
+ ``consumer`` script to watch the input folder, and the ``scheduler``
+ script to run tasks such as email checking and document consumption.
+
+ These services rely on redis and optionally the database server, but
+ don't need to be started in any particular order. The example files
+ depend on redis being started. If you use a database server, you should
+ add additinal dependencies.
+
+ .. hint::
+
+ You may optionally set up your preferred web server to serve
+ paperless as a wsgi application directly instead of running the
+ ``webserver`` service. The module containing the wsgi application
+ is named ``paperless.wsgi``.
+
+ .. caution::
+
+ The included scripts run a ``gunicorn`` standalone server,
+ which is fine for running paperless. It does support SSL,
+ however, the documentation of GUnicorn states that you should
+ use a proxy server in front of gunicorn instead.
+
+11. Optional: Install a samba server and make the consumption folder
+ available as a network share.
+
+12. Configure ImageMagick to allow processing of PDF documents. Most distributions have
+ this disabled by default, since PDF documents can contain malware. If
+ you don't do this, paperless will fall back to ghostscript for certain steps
+ such as thumbnail generation.
+
+ Edit ``/etc/ImageMagick-6/policy.xml`` and adjust
+
+ .. code::
+
+
+
+ to
+
+ .. code::
+
+
Migration to paperless-ng
#########################
diff --git a/scripts/make-release.sh b/scripts/make-release.sh
index 3c3892aed..0a7bc7a9b 100755
--- a/scripts/make-release.sh
+++ b/scripts/make-release.sh
@@ -42,6 +42,7 @@ fi
mkdir "$PAPERLESS_DIST"
mkdir "$PAPERLESS_DIST_APP"
mkdir "$PAPERLESS_DIST_APP/docker"
+mkdir "$PAPERLESS_DIST_APP/scripts"
mkdir "$PAPERLESS_DIST_DOCKERFILES"
# setup dependencies.
@@ -104,6 +105,11 @@ cp "$PAPERLESS_ROOT/docker/gunicorn.conf.py" "$PAPERLESS_DIST_APP/docker/"
cp "$PAPERLESS_ROOT/docker/imagemagick-policy.xml" "$PAPERLESS_DIST_APP/docker/"
cp "$PAPERLESS_ROOT/docker/supervisord.conf" "$PAPERLESS_DIST_APP/docker/"
+# auxiliary files for bare metal installs
+cp "$PAPERLESS_ROOT/scripts/paperless-webserver.service" "$PAPERLESS_DIST_APP/scripts/"
+cp "$PAPERLESS_ROOT/scripts/paperless-consumer.service" "$PAPERLESS_DIST_APP/scripts/"
+cp "$PAPERLESS_ROOT/scripts/paperless-scheduler.service" "$PAPERLESS_DIST_APP/scripts/"
+
# try to make the docker build.
cd "$PAPERLESS_DIST_APP"
diff --git a/scripts/paperless-consumer.service b/scripts/paperless-consumer.service
index 79a27d3ce..04512b719 100644
--- a/scripts/paperless-consumer.service
+++ b/scripts/paperless-consumer.service
@@ -1,10 +1,12 @@
[Unit]
Description=Paperless consumer
+Requires=redis.service
[Service]
User=paperless
Group=paperless
-ExecStart=/home/paperless/project/virtualenv/bin/python /home/paperless/project/src/manage.py document_consumer
+WorkingDirectory=/opt/paperless/src
+ExecStart=python3 manage.py document_consumer
[Install]
WantedBy=multi-user.target
diff --git a/scripts/paperless-scheduler.service b/scripts/paperless-scheduler.service
new file mode 100644
index 000000000..c565d8af4
--- /dev/null
+++ b/scripts/paperless-scheduler.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Paperless consumer
+Requires=redis.service
+
+[Service]
+User=paperless
+Group=paperless
+WorkingDirectory=/opt/paperless/src
+ExecStart=python3 manage.py qcluster
+
+[Install]
+WantedBy=multi-user.target
diff --git a/scripts/paperless-webserver.service b/scripts/paperless-webserver.service
index 8ff746be2..a43110be2 100644
--- a/scripts/paperless-webserver.service
+++ b/scripts/paperless-webserver.service
@@ -2,11 +2,13 @@
Description=Paperless webserver
After=network.target
Wants=network.target
+Requires=redis.service
[Service]
User=paperless
Group=paperless
-ExecStart=/home/paperless/project/virtualenv/bin/gunicorn --pythonpath=/home/paperless/project/src paperless.wsgi -w 2
+WorkingDirectory=/opt/paperless/src
+ExecStart=/opt/paperless/.local/bin/gunicorn paperless.wsgi -w 2 -b 0.0.0.0:8000
[Install]
WantedBy=multi-user.target
diff --git a/src-ui/src/app/components/common/tag/tag.component.html b/src-ui/src/app/components/common/tag/tag.component.html
index a83c53c77..8b9632a65 100644
--- a/src-ui/src/app/components/common/tag/tag.component.html
+++ b/src-ui/src/app/components/common/tag/tag.component.html
@@ -1,2 +1,2 @@
{{tag.name}}
-{{tag.name}}
\ No newline at end of file
+{{tag.name}}
\ No newline at end of file
diff --git a/src-ui/src/app/components/common/tag/tag.component.ts b/src-ui/src/app/components/common/tag/tag.component.ts
index ec59e86f3..c032c51db 100644
--- a/src-ui/src/app/components/common/tag/tag.component.ts
+++ b/src-ui/src/app/components/common/tag/tag.component.ts
@@ -14,10 +14,10 @@ export class TagComponent implements OnInit {
tag: PaperlessTag
@Input()
- clickable: boolean = false
+ linkTitle: string = ""
- @Output()
- click = new EventEmitter()
+ @Input()
+ clickable: boolean = false
ngOnInit(): void {
}
diff --git a/src-ui/src/app/components/document-detail/document-detail.component.ts b/src-ui/src/app/components/document-detail/document-detail.component.ts
index 21ed6a4a5..7c396692e 100644
--- a/src-ui/src/app/components/document-detail/document-detail.component.ts
+++ b/src-ui/src/app/components/document-detail/document-detail.component.ts
@@ -1,4 +1,3 @@
-import { DatePipe, formatDate } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
@@ -7,17 +6,14 @@ import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent';
import { PaperlessDocument } from 'src/app/data/paperless-document';
import { PaperlessDocumentMetadata } from 'src/app/data/paperless-document-metadata';
import { PaperlessDocumentType } from 'src/app/data/paperless-document-type';
-import { TAG_COLOURS, PaperlessTag } from 'src/app/data/paperless-tag';
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
import { OpenDocumentsService } from 'src/app/services/open-documents.service';
import { CorrespondentService } from 'src/app/services/rest/correspondent.service';
import { DocumentTypeService } from 'src/app/services/rest/document-type.service';
import { DocumentService } from 'src/app/services/rest/document.service';
-import { TagService } from 'src/app/services/rest/tag.service';
import { DeleteDialogComponent } from '../common/delete-dialog/delete-dialog.component';
import { CorrespondentEditDialogComponent } from '../manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component';
import { DocumentTypeEditDialogComponent } from '../manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component';
-import { TagEditDialogComponent } from '../manage/tag-list/tag-edit-dialog/tag-edit-dialog.component';
@Component({
selector: 'app-document-detail',
@@ -140,8 +136,8 @@ export class DocumentDetailComponent implements OnInit {
close() {
this.openDocumentService.closeDocument(this.document)
- if (this.documentListViewService.viewId) {
- this.router.navigate(['view', this.documentListViewService.viewId])
+ if (this.documentListViewService.savedViewId) {
+ this.router.navigate(['view', this.documentListViewService.savedViewId])
} else {
this.router.navigate(['documents'])
}
diff --git a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.html b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.html
index 305cb37d2..63a8bf710 100644
--- a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.html
+++ b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.html
@@ -7,7 +7,12 @@