Assets tree
The assets tree is the mirror of the cloud folder Damvia synchronizes from Dropbox or OneDrive. Administrators do not upload files here; they browse what the sync brought in and decide, per folder, which asset type and license apply. Everything else on this page happens in background jobs.
The screen
Section titled “The screen”/admin/assets/:id? (admin only) has a resizable left panel headed OneDrive Folders that lists the root folders, and a main panel with a breadcrumb starting at Assets. Without an id it shows the root folders; with an id it shows:
- an
Asset Typeselect (No asset typeor one of the types) and aLicenseselect (No licenseor one of the licenses), followed by aSavebutton, - the subfolders as folder icons,
- the files with their thumbnail, an extension badge and their name.
Save calls asset.update, which applies both selects to the folder, all its descendant folders and all files in them. The toast reads Asset Types and License settings saved. How each value is used is described in Asset types and Licenses.
What the sync writes
Section titled “What the sync writes”server/src/index.ts starts the updater chosen by ASSET_UPDATER, calls fetchUpdates() and reschedules it 5 minutes after each run finishes. After every run it inserts any missing collection_files rows for files whose folder is linked to a collection. The updater upserts folders and files through server/src/services/asset.ts:
| Table | Key | Written fields |
|---|---|---|
asset_folders |
external_id (unique) |
name, parent_id, status, inherited asset_type_id and license_id on create or move |
asset_files |
external_id (unique) |
name, size, mime_type, external_checksum, folder_id, asset_type_id and license_id copied from the folder |
Items that disappeared from the source are flagged pending_deletion in batches of 1,000 rather than deleted on the spot. A new file is created with status creating and a job is pushed to asset/update-content; a file that changed folder has its collection_files rows moved to the collections of the new folder.
File and folder statuses
Section titled “File and folder statuses”| Entity | Status | Meaning |
|---|---|---|
| file | creating |
Row exists, content not yet fetched |
| file | up_to_date |
Content and thumbnail stored |
| file | outdated |
Content must be fetched again; set by the daily system/integrity-check job when it finds files to re-sync |
| file | pending_deletion |
Gone from the source, waiting for the deletion job |
| folder | up_to_date |
Present in the source |
| folder | pending_deletion |
Gone from the source, waiting for the deletion job |
The asset/update-content job
Section titled “The asset/update-content job”Processed 10 jobs at a time, updateFileContent:
- Downloads the file from the source through the updater.
- Detects the MIME type with
file-type(awebpresult is stored asimage/webp; unknown types fall back toapplication/octet-stream). - Uploads the original to the assets bucket under
asset-file/{id}with thatContent-Type. - Generates a thumbnail and uploads it under
asset-file/{id}-thumbnailasimage/webp, settinghas_thumbnail. If no thumbnail can be produced, an existing one is removed. - Extracts
widthandheight:ffprobefor videos,sharpmetadata for images (with pixel limits disabled for TIFF and files over 50 MB),magick identifyfor PSD, and a fixed 1920 by 1280 for fonts. - Sets the status to
up_to_dateand deletes the temporary files.
Storage settings are covered in Object storage.
Thumbnails by file family
Section titled “Thumbnails by file family”server/src/services/image-processor.ts picks a pipeline from the extension or MIME type:
| Family | Extensions | Tool |
|---|---|---|
| Images | jpg, jpeg, png, gif, bmp, webp, tiff, tif, svg, psd |
sharp, with ImageMagick convert for the cases sharp cannot read |
| Vector and PDF | pdf, eps, ai |
Ghostscript renders the first page to PNG |
| Office and text | doc, docx, xls, xlsx, ppt, pptx, odt, ods, odp, rtf, pps, ppsx, potx, pot, html, htm, xml, json, md, yaml, yml, txt, css, js, ts, csv |
soffice --headless --convert-to pdf, then Ghostscript |
| Video | mp4, mov, avi, mkv, wmv, flv, webm, m4v |
ffmpeg extracts a frame |
| Fonts | ttf, otf |
ImageMagick renders a sample text with the font |
Intermediate PNGs are resized to a height of 1,280 pixels and encoded as WebP with sharp. Every thumbnail stored in the bucket is WebP. Files outside these families get no thumbnail and the client shows a placeholder.
The server/Dockerfile installs the required system packages on node:20: ffmpeg, ghostscript, libreoffice, coreutils and imagemagick. A server running outside that image needs the same tools on its PATH.
The asset/process-deletion job
Section titled “The asset/process-deletion job”Scheduled every minute (* * * * *), processDeletion first deletes every file in pending_deletion, then every folder in pending_deletion:
deleteFileremoves thecollection_filesrows, theasset_filesrow, and both objectsasset-file/{id}andasset-file/{id}-thumbnail, in one transaction.deleteFolderrecurses into child folders, deletes their files, deletes every collection whoseasset_folder_idis the folder, then removes the folder row.
Job names and schedules are summarized in Background jobs.