Skip to content

Latest commit

 

History

1,431 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CI

Paper Manager

Paperman is an electronic filing cabinet: it scans paper into stacks of pages and lets you view, arrange, annotate, print, search and send them. It reads and writes PDF, JPEG and its own variant of PaperPort's .max file format, and runs on Linux, Windows and macOS.

On Ubuntu, install it from the PPA (ppa:sjg1/ppa). Windows installers come with releases from the next one on, and until then from the artifacts of the latest CI run on master. See the installation guide for the rest, including macOS.

Full documentation is available at https://paperman.readthedocs.io

Desktop view Select scanner Dated files Open file Preview Preview2
1 2 3 4 5 6
Scanning Fast folder finding Scanning dialog Side-by-side preview & OCR
7 8 9 10

Features

  • simple GUI based around stacks and pages
  • view previews and browse through pages
  • move pages in and out of stacks
  • navigate through directories
  • move stacks between directories
  • double click to view full size page image (also on right pane)
  • print stacks and pages, including page annotations
  • email files as PDF via Gmail (Ctrl+Shift+E, paste with Ctrl+V)
  • copy files as PDF to the clipboard (Ctrl+C, paste anywhere)
  • full undo/redo
  • fast scanning from sheet-fed scanners, through SANE on Linux and macOS and TWAIN on Windows, with presets; pages cut to the sheet and straightened, colourless pages stored as grey or mono, blank pages left out, sheets fed sideways turned upright, and a misfeed or jam waiting to be cleared without losing pages (see the scanning guide)
  • scanning from the command line (--scan)
  • OCR with full-text search
  • a search server whose repositories the desktop can show and change over the network

new in 0.4:

  • basic scanning
  • partial creation of .max files (but monochrome images are uncompressed) (also it doesn't create greyscale/colour previews)

new in 0.5:

  • better scanning, should now work properly with SANE and most scanners
  • stacking/unstacking, moving files between directories, etc.
  • colour previews are created (greyscale still not sorry)
  • PDF, JPEG and TIFF conversion supported. Results may vary
  • View quality menu to trade speed for quality

new in 0.7:

  • better multithreaded scanning
  • undo/redo
  • better PDF support
  • preview panes
  • OCR engine
  • zooming in and out in preview windows (hold down control and use mouse wheel)
  • rewritten for QT4
  • many many other changes and improvements

new in 0.7.1:

  • a few bug fixes

new in 0.8

  • first github release
  • new icon
  • cleaned up README

new in 1.0

  • fully ported to QT4
  • should build on very modern distributions that don't have QT3

new in 1.0.1

  • builds with QT5, including on Ubuntu 20.04 Focal

new in 1.1

  • presets for scanning, use Ctrl-1 to Ctrl-6 to quickly select
  • fast folder finding in the scanning dialogue
    • type the partial match in the 'Folder' field (press F6 to get there)
    • it expects directories to be called yyyy and mmMMM, e.g. 2024/03mar/...
    • press to scan, or click on the match to just create the dir
  • filtering out of directories which don't match the current year / month
  • keyboard shortcuts for A4 (Alt-A) and US letter/legal toggle (Alt-L)
  • Fix most warnings

new in 1.2

  • Import files from outside directories
  • Avoid keeping all touched-files open
  • Bring back command-line operation
  • Presets (Ctrl-1 to Ctrl-6) for basic scanning operation
  • Faster folder-selection within the scanning window
  • Set the group for files

new in 1.2.1

  • Expand tests to include common stacking/unstacking operations
  • Fix various bugs in recent new features, particularly files not being opened before use

new in 1.3

  • Fix problems with dir cache being out of date
  • Add more tests for Dirmodel
  • Drop the 'recently used' folder
  • Set permissions on created files and directories

new in 1.3.1

  • support Ubuntu oracular
  • update build scripts to work on 24.04 host
  • more tweaks to the findFolders() feature

new since 1.3.3 (not yet released)

  • runs on Windows (10 and 11, x64 and Arm, with an installer) and macOS
  • a TWAIN back end for scanners on Windows
  • scanning: auto size and straightening by the scanner, auto colour, blank-page detection in colour, sideways feeding, a Long size for sheets longer than Legal, recovery from misfeeds and jams, Stop keeping the sheets already fed, and much faster transfer from Fujitsu scanners
  • scanning from the command line, with --log and --sane-debug for finding out what went wrong
  • unfolding scanned booklets into their pages
  • working with repositories on a paperman server: browsing, opening, changing and scanning into them, with changes shown as they happen
  • a first run which offers somewhere to keep papers and lays the window out to suit the screen
  • a fake Fujitsu scanner for testing without paper (Linux)

Command-line usage

-j

Convert a file to .jpg, the JPEG image file. This produces a separate file for each page of the document, with a _p addition. So a two-page document called fred,max will produce fred_p1.jpg and fred_p2.jpg

-m

Convert a file to .max, Paperman's native format. The new file has the same name but with a .max extension.

-p

Convert a file to PDF, The new file has the same name but with a .pdf extension.

-s

Does an MD5 checksum of every page in every .max file in a directory. The results are written to a file called 'checksums.md5' in the current directory. For example:

maxview -s /paper

The file format is a line for each page, containing space-separated fields:

Length of filename in characters
Filename
Page number
Image size in bytes
md5 checksum, grouped by 32-bit words

For example:

27 Property taxes  pd 2020.max 0 1093872 a3eb8cd8 b0cffff0 b845833c e370368e
27 Property taxes  pd 2020.max 1 1093872 40f34c34 ae5f9549 158f97ab d6c1e6a8
27 Property taxes  pd 2020.max 2 1093872 78572475 16422b9a c900d2a7 61ce49d6
27 Property taxes  pd 2020.max 3 1093872 96562c4e cebfc3b3 5c863b22 d80abde6

--scan [--repo DIR] [--dir SUBDIR] [--device NAME] [--pages N]

Scans into a repository without showing the GUI, using the saved scanner settings. The stack goes into the top-level directory of the first configured repository unless --repo and --dir say otherwise, and the scanner is the last one used unless --device names another. --pages stops after that many sides; otherwise scanning continues until the feeder is empty. --set NAME=VALUE sets a scanner option by its SANE name before the scan (for example mode=Color, resolution=200, source="ADF Duplex" or page-height=355.6, with fixed-point values in their units) and can be repeated. --auto-colour stores pages that turn out to have no colour as greyscale, or as mono when they have no shading either, as the Auto colour box in the scan window does. Progress is printed on stdout and the exit code is 0 if at least one page was scanned. For example, to scan two pages in colour into the 'inbox' directory of the repository in ~/paper:

paperman --scan --repo ~/paper --dir inbox --pages 2 --set mode=Color

For a benchmark or a test scan that should not end up in a real repository, point --repo at a throwaway directory: it is used for that run only and is not added to the configured repositories.

mkdir -p /tmp/bench && paperman --scan --repo /tmp/bench --pages 50

Before every scan paperman turns on the fast-transfer settings a backend offers: buffermode=On, so a scanner with memory scans ahead instead of stopping after each sheet, and in colour compression=JPEG, so a side arrives as under 1 MB rather than 25 MB. Both matter over USB (the patched fujitsu backend has them; the fi-8950 runs at a third of its speed without). A None chosen for compression in the scan dialog is respected, and --set still overrides either.

With PAPERMAN_SCAN_STATS=1 in the environment, paperman prints a line of statistics on stderr at the end of every scan, in the GUI as well as with --scan: sides scanned, time per side, CPU used by the display and scanning threads, and how far the display fell behind the scanner. This is the first thing to look at if scanning seems slow, since it says which side is the bottleneck.

To measure the scanner itself, tools/psip-bench.py talks the fi-8950's network protocol directly, with neither the SANE backend nor paperman in the way: it scans a number of sides (default 50) as fast as the scanner will hand them over, prints the timing of every side with -v, and reports the rate, how long the scanner made it wait for each side, and how far the feeder ran ahead. Options vary resolution, pre-pick, divided delivery and end-of-page detection. It always stops the feeder and closes the session, so it can be interrupted with Ctrl-C.

tools/sane-bench.py does the same through SANE with scanimage, so it works over USB (fujitsu backend) as well as the network, timing each side as it completes; for a fujitsu device it adds buffermode=On and, in colour, compression=JPEG, which the fi-8950 needs to run at speed over USB.

With PAPERMAN_SNAP=<dir> set (or --snap <dir>), paperman saves a snapshot of its window as it appears on screen once a second, as snap-NNNN-<seconds>s.jpg in that directory; --clean-snaps (or PAPERMAN_SNAP_CLEAN=1) removes the snapshots already there first. This shows what the display actually showed and when, to set against a log, which is useful when the display seems to lag behind what paperman reports. It grabs from paperman's own event loop, so it misses the moments paperman is busy, and it captures screen pixels, so it needs X11 (on Wayland the snapshots come out empty).

-o | --ocr

Recursively process all .max files in a directory, performing OCR (Optical Character Recognition) on each page and saving the extracted text. The OCR text is saved both within the .max file as an annotation and in a searchable SQLite FTS5 index.

Features:

  • Processes all .max files recursively in the specified directory
  • Runs Tesseract OCR on each page to extract text
  • Saves OCR text as an annotation in the .max file
  • Builds a full-text search index (.paperindex) for fast searching
  • If a file already has OCR text, it indexes the existing text without re-OCRing
  • Runs in console mode (no GUI required)

Example:

paperman --ocr /paper/2024

This will:

  1. Scan all .max files in /paper/2024 and subdirectories
  2. Run OCR on each page (or use existing OCR text if available)
  3. Save the extracted text in each .max file
  4. Create a searchable index at /paper/2024/.paperindex

-q [directory] | --search [directory]

Search the OCR text index for files containing the specified query. Returns a list of matching files with page numbers and text snippets showing the context.

Features:

  • Full-text search using SQLite FTS5 with porter stemming
  • Returns ranked results with highlighted search terms
  • Shows file path, filename, page number, and text snippet for each match
  • Supports complex queries and boolean operators
  • Runs in console mode (no GUI required)

Example:

paperman --search "invoice" /paper/2024

This will search the index at /paper/2024/.paperindex and display results like:

Found 3 results:

[1] expenses-jan.max (page 2)
    Path: /paper/2024/01jan/expenses-jan.max
    ...payment details for <b>invoice</b> #12345...

[2] receipts.max (page 1)
    Path: /paper/2024/02feb/receipts.max
    ...<b>invoice</b> dated February 15th...

If no directory is specified, searches the current directory.

Note: You must run --ocr on a directory first to create the search index.

--fake-scanner DIR

Offers a fake Fujitsu fi-8170 beside the real scanners, for trying something out without a scanner or paper to hand. It is listed as FUJITSU fi-8170 (fake) and scans pictures put in DIR/hopper: page.png is the front of a sheet and page.back.png its back, fed in order of name. touch DIR/press-scan presses its Scan button. Setting PAPERMAN_FAKE_SCANNER=DIR does the same. It is built on Linux only; see doc/testing.rst for what it can do.

paperman --fake-scanner /tmp/fs

Windows

There is an installer for x64 PCs (paperman-setup-VERSION.exe) and one for Windows on Arm (paperman-setup-VERSION-arm64.exe), with each release from the next one on, and built by every CI run meanwhile; it needs Windows 10 version 1809 or later, and no administrator. To scan, install the scanner's 64-bit TWAIN driver: for the Ricoh fi-series that is PaperStream IP (TWAIN x64), a separate download from the 32-bit one. Sign out and back in after installing it, since PaperStream only sets the scanner up for TWAIN when the user logs in.

To build it, use the MSYS2 MinGW64 toolchain, which is also what the CI job uses. In a MINGW64 shell:

pacman -S make mingw-w64-x86_64-gcc mingw-w64-x86_64-pkgconf \
    mingw-w64-x86_64-qt6-base mingw-w64-x86_64-qt6-scxml \
    mingw-w64-x86_64-poppler-qt6 mingw-w64-x86_64-podofo \
    mingw-w64-x86_64-libtiff mingw-w64-x86_64-libjpeg-turbo \
    mingw-w64-x86_64-tesseract-ocr mingw-w64-x86_64-tesseract-data-eng
qmake6 paperman.pro -o Makefile.win
make -f Makefile.win

make -f Makefile.win installer builds the installer too, with Inno Setup installed.

Scanners are driven through TWAIN rather than SANE: every TWAIN data source installed on the machine appears in the device list. The TWAIN back end lives in win32/twainsane.cpp and presents the same options as SANE's fujitsu backend.

When bringing up a new scanner, run paperman from a shell with PAPERMAN_TWAIN_DEBUG=1 set: it logs every TWAIN operation and the capabilities the driver reports to stderr. If colours come out with red and blue swapped, set PAPERMAN_TWAIN_RGB=1. PAPERMAN_TWAIN_DUMP=<file> writes the first scanned image as a PBM/PGM/PPM, exactly as the back end hands it to paperman, which separates driver problems from filing problems. Only the TWAIN 2 data source manager (TWAINDSM.dll, installed with any current driver) is used; set PAPERMAN_TWAIN_LEGACY=1 to fall back to the twain_32.dll shipped with Windows.

macOS

Paperman builds on macOS with Qt 6 and Homebrew. Homebrew's Poppler has no Qt bindings, so Poppler is built separately:

brew install pkgconf podofo libtiff jpeg-turbo sane-backends cmake ninja \
    openjpeg little-cms2 fontconfig
# Qt 6 from qt.io, or with aqtinstall:
#    aqt install-qt mac desktop 6.11.3 clang_64 -m qtscxml -O ~/Qt
curl -LO https://poppler.freedesktop.org/poppler-26.09.0.tar.xz
tar xf poppler-26.09.0.tar.xz
cmake -S poppler-26.09.0 -B pbuild -G Ninja -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=$HOME/poppler \
    -DCMAKE_PREFIX_PATH="$HOME/Qt/6.11.3/macos;$(brew --prefix)" \
    -DENABLE_QT5=OFF -DENABLE_GLIB=OFF -DENABLE_NSS3=OFF \
    -DENABLE_GPGME=OFF -DENABLE_LIBCURL=OFF -DENABLE_BOOST=OFF \
    -DENABLE_HARFBUZZ=OFF
ninja -C pbuild install
export PKG_CONFIG_PATH=$HOME/poppler/lib/pkgconfig:$(brew --prefix)/lib/pkgconfig
~/Qt/6.11.3/macos/bin/qmake6 paperman.pro -o Makefile
make -f Makefile

That makes paperman.app; a build with CONFIG+=test makes a plain paperman instead, for the tests. Use make -f Makefile, since the GNUmakefile in the repository builds the other programs too. Scanners are reached through SANE, as on Linux, from Homebrew's sane-backends; a scanner too recent for that release, such as the fi-8950, needs a newer SANE built from source. On an Intel Mac, Homebrew has no ready-built packages for the latest macOS, so brew install needs --build-from-source.

Code signing policy

Free code signing provided by SignPath.io, certificate by SignPath Foundation.

Only the Windows program and installer which this project builds are signed, by its release workflow, once an approver approves each release. Committers, reviewers and approvers: Simon Glass (@sjg20).

This program will not transfer any information to other networked systems unless specifically requested by the user or the person installing or operating it.

See the full policy for how releases are signed.

Testing

Paperman includes a comprehensive test suite to verify functionality. Tests are built using the Qt Test framework.

Building with Tests

To build paperman with test support enabled:

qmake "CONFIG+=test" paperman.pro
make

Running Tests

Run all tests:

env QT_QPA_PLATFORM=offscreen ./paperman -t

This will run all test suites including:

  • utils - Utility function tests
  • ops - File operation tests (duplicate, stack, unstack, rename, etc.)
  • searchserver - HTTP search server tests
  • ocrsearch - OCR indexing and search functionality tests

OCR Search Tests

The OCR search test suite (test/test_ocrsearch.cpp) includes:

  1. testOcrIndexing() - Tests creating a search index and adding OCR text
  2. testOcrSearch() - Tests searching indexed text and verifying results
  3. testReindexing() - Tests re-indexing existing OCR text
  4. testSearchNoResults() - Tests handling of queries with no matches

All tests use temporary directories and clean up after themselves.

Test Output Example

********* Start testing of TestOcrSearch *********
PASS   : TestOcrSearch::initTestCase()
PASS   : TestOcrSearch::testOcrIndexing()
PASS   : TestOcrSearch::testOcrSearch()
PASS   : TestOcrSearch::testReindexing()
PASS   : TestOcrSearch::testSearchNoResults()
PASS   : TestOcrSearch::cleanupTestCase()
Totals: 6 passed, 0 failed, 0 skipped, 0 blacklisted
********* Finished testing of TestOcrSearch *********

Future Features

Here's what I'd like it to support:

  • more operations on images
  • support for more image types (at the moment only JPEG is supported)

If you have other ideas then feel free to let me know on the mailing list.

Simon Glass sjg@chromium.org Aug 2020

About

Paper managing and scanning - an electronic filing cabinet

Resources

Stars

34 stars

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages