Resources
Every file in Mahresources is a Resource: images, documents, videos, or anything else. Each file is hashed for deduplication, gets automatic thumbnails where supported, and has version history.

Resource Properties
| Property | Description |
|---|---|
name | Display name for the resource |
originalName | Original filename when uploaded |
originalLocation | Source URL or path if imported |
description | Free-text description |
meta | Arbitrary JSON metadata |
contentType | MIME type (e.g., image/jpeg) |
contentCategory | Content category string (e.g., image, video, document) |
category | Legacy category string |
fileSize | Size in bytes |
width, height | Dimensions for images and videos |
hash | Content hash for deduplication |
hashType | Hash algorithm used (SHA1) |
location | Storage path relative to the storage root |
storageLocation | Which alternative filesystem contains the file (nil = default) |
resourceCategoryId | Optional Resource Category for typed presentation |
seriesId | FK to Series for shared metadata grouping |
ownMeta | Resource-specific metadata when in a Series (diff from Series meta) |
ownerId | FK to owner Group |
currentVersionId | ID of the active version (see Versioning) |
createdAt | Creation timestamp |
updatedAt | Last update timestamp |
Resource descriptions support @-mentions — type @ in the description field to search and link to notes, groups, and tags. Mentioned entities are automatically added as relations when you save. See Mentions.
File Storage
Mahresources stores files on the filesystem and metadata in the database:
- Files are organized by hash for deduplication
- Multiple storage locations can be configured via alternative filesystems
- The
locationfield stores the path relative to the storage root - The optional
storageLocationfield specifies which filesystem contains the file
Alternative Filesystems
Configure multiple storage locations for:
- Separating different types of content
- Read-only archive storage
- Distributed storage across drives
Thumbnails and Previews
Mahresources generates thumbnails automatically for supported file types:
Image Thumbnails
- Generated on-demand when first requested for a given size
- Supports JPEG, PNG, GIF, WebP, BMP, TIFF natively; HEIC/AVIF via ImageMagick fallback; SVG via built-in rasterizer (oksvg/rasterx)
- Cached in the database as
Previewrecords for subsequent requests
Video Thumbnails
- Requires FFmpeg to be installed and configured
- Extracts a frame from the video at 1 second (with fallback to 0s)
- A background ThumbnailWorker pre-generates thumbnails for video resources
- Configure via
-ffmpeg-pathorFFMPEG_PATH
Document Thumbnails
- Requires LibreOffice for office documents
- Converts first page to image preview
- Configure via
-libreoffice-pathorLIBREOFFICE_PATH - Auto-detects
sofficeorlibreofficein PATH
Hash Calculation
Mahresources computes cryptographic hashes for integrity and deduplication:
Content Hash
- SHA1 hash of file contents
- Used for deduplication (same content = same hash)
- Enables detection of duplicate uploads
Perceptual Hashes (Images)
For image files, Mahresources computes two perceptual hashes using the imgsim library: AHash (average hash) and DHash (difference hash). Both are stored in the database, but DHash is used for similarity comparison. Similarity between two images is measured by the Hamming distance between their DHash values -- the number of differing bits.
Perceptual hashes detect visually similar images even across different resolutions, minor edits, format conversions, and color adjustments.
Image Similarity
A background worker compares perceptual hashes across all images and stores similarity pairs. When viewing an image, Mahresources displays visually similar images ranked by Hamming distance. For configuration options and details, see Image Similarity.
Resource Versioning
Mahresources tracks version history for each Resource. For details, see Versioning.
Version Properties
| Property | Description |
|---|---|
versionNumber | Sequential version number |
hash | Content hash for this version |
fileSize | Size of this version |
contentType | MIME type (may change between versions) |
width, height | Dimensions for this version |
location | Storage path for this version |
storageLocation | Which filesystem contains this version's file |
hashType | Hash algorithm used (defaults to SHA1) |
comment | Optional description of changes |
Version Workflow
- Upload a new file to an existing resource
- Previous content is preserved as a version
- New content becomes the current version
- Access any version through the version history
Series Membership
A Resource can belong to a Series -- a grouping of Resources that share common metadata (e.g., pages of a scanned document). The Series holds shared metadata, and each Resource stores only its unique differences in ownMeta. The effective meta is the merge of Series meta plus ownMeta (Resource wins on conflict). See Series.
Duplicate Detection
Upload deduplication is hash-based (SHA1). If a file with the same hash already exists:
- Same owner: Returns a
ResourceExistsErrorwith the existing Resource ID - Different owner: Attaches the new owner as a related Group on the existing Resource
Deletion Behavior
Deleted files are backed up to the /deleted/ directory before the database record is removed. The backup file is named using the format {hash}__{id}__{ownerId}___{basename} to prevent collisions and preserve context. Files are only physically deleted from primary storage if no other Resources or versions reference the same hash.
Relationships
Resources connect to other entities in several ways:
Ownership
- A Resource can be owned by one Group
- The owner appears as the resource's parent
- Deleting the owner sets the resource's owner to NULL
Related Groups
- A Resource can be related to multiple Groups
- Appears in each group's "Related Resources" section
- Many-to-many relationship
Related Notes
- A Resource can be attached to multiple Notes
- Notes can reference resources as attachments
- Many-to-many relationship
Tags
- A Resource can have multiple Tags
- Tags enable cross-cutting organization
- Many-to-many relationship
API Operations
For full API details -- creating, querying, and bulk operations on Resources -- see API: Resources.