mayan.apps.sources*Le système de sources est le point d'entrée des documents dans Mayan EDMS. Il définit d'où et comment les fichiers sont importés. L'architecture repose sur une composition de mixins : chaque type de source est assemblé en combinant des briques fonctionnelles indépendantes.
Les apps source* sont au nombre de 13 :
| App | Rôle |
|---|---|
sources |
Framework de base — modèle, actions, permissions, tâches |
source_compressed |
Mixin décompression ZIP/archives |
source_emails |
Sources email IMAP et POP3 |
source_generated_files |
Sources générant des fichiers à la demande |
source_interactive |
Mixin sources interactives (utilisateur présent) |
source_periodic |
Mixin sources automatiques (planifiées) |
source_sane_scanners |
Scanner physique via SANE/scanimage |
source_staging_folders |
Dossier de staging sur filesystem |
source_staging_storages |
Dossier de staging sur storage backend |
source_stored_files |
Fichiers stockés — base pour staging et watch |
source_watch_folders |
Dossier surveillé automatiquement (filesystem) |
source_watch_storages |
Dossier surveillé automatiquement (storage backend) |
source_web_forms |
Formulaire web HTML5 upload |
sources — Framework de baseSourceSource
├── label CharField(128, unique) — nom affiché
├── enabled BooleanField — activation/désactivation
└── backend_data JSONField — configuration du backend
Source hérite de BackendModelMixin : le type de source est stocké comme chemin Python dans backend_data. L'instance du backend est créée dynamiquement.
DocumentFileSourceMetadataStocke des métadonnées arbitraires sur un fichier importé (ex: headers email, nom du dossier source).
DocumentFileSourceMetadata
├── document_file FK(DocumentFile)
├── key CharField(255) — ex: "email_subject", "source_id"
└── value TextField
SourceBackendAction)Chaque backend expose une liste d'actions. Une action correspond à une opération (upload nouveau document, upload nouvelle version, supprimer un fichier staging…). Les actions s'exécutent soit :
| Tâche | Description |
|---|---|
task_source_backend_action_execute |
Exécute une action de source (sources périodiques). Protégée par verrou distribué pour éviter les doublons. Non retryable (évite d'importer deux fois). |
task_source_backend_action_background_task |
Exécute une action en arrière-plan (sources interactives). Retryable avec backoff. |
Namespace : sources_setup
| Permission | Description |
|---|---|
permission_sources_view |
Voir la liste des sources |
permission_sources_create |
Créer une source |
permission_sources_edit |
Modifier une source |
permission_sources_delete |
Supprimer une source |
permission_document_file_sources_metadata_view |
Voir les métadonnées de source d'un fichier |
SourceBackendMixinRegularExpression)Ajoute deux champs à n'importe quelle source :
include_regex — seuls les fichiers dont le nom correspond sont traitésexclude_regex — les fichiers dont le nom correspondent sont ignorés⚠️ Ces champs sont rendus via le moteur de templates Django avant compilation en regex (vulnérabilité VULN 9 — security2_report.txt).
| Événement | Déclencheur |
|---|---|
event_source_created |
Création d'une source |
event_source_edited |
Modification d'une source |
Source.save()
→ backend.clean() # validation
→ backend.create() # si nouvelle source (crée tâche périodique, etc.)
→ backend.update() # si modification
Source.delete()
→ backend.delete() # nettoyage (supprime tâche périodique, etc.)
→ super().delete()
source_compressed — Décompression d'archivesMixin ajouté à n'importe quelle source pour gérer les archives compressées (ZIP, TAR, etc.). Chaque fichier de l'archive est importé comme document séparé.
| Champ | Valeurs | Description |
|---|---|---|
uncompress |
always / ask / never |
Comportement face aux archives |
| Mode | Description |
|---|---|
always |
Toutes les archives sont automatiquement décompressées |
ask |
L'utilisateur choisit via une case à cocher dans le formulaire |
never |
Les archives sont importées telles quelles |
Pour les sources non-interactives (périodiques), seuls always et never sont disponibles.
source_emails — Sources email| Classe | Label | Protocole |
|---|---|---|
SourceBackendIMAPEmail |
IMAP email | IMAP / IMAP over SSL |
SourceBackendPOP3Email |
POP3 email | POP3 / POP3 over SSL |
| Champ | Description |
|---|---|
host |
Serveur email |
port |
Port (110/995 POP3, 143/993 IMAP) |
ssl |
Activer SSL |
store_body |
Importer le corps du message comme document texte |
| Credentials | Identifiants via le système credentials de Mayan |
| Champ | Default | Description |
|---|---|---|
mailbox |
INBOX |
Dossier IMAP à surveiller |
search_criteria |
UNSEEN |
Critères RFC 2060 |
store_commands |
+FLAGS (\Seen) |
Commandes IMAP post-traitement (une par ligne) |
execute_expunge |
True |
Exécuter EXPUNGE après traitement |
mailbox_destination |
vide | Déplacer les messages traités vers ce dossier |
Le traitement est récursif pour gérer les emails multipart :
DocumentFileSourceMetadata avec préfixe email_email_body.txt / email_body.html si store_body=TrueuncompressÀ chaque tick :
search_criteriarandom.choice)store_commands (ex: marquer lu)source_generated_files — Fichiers générés à la demandeMixin pour les sources qui génèrent un fichier au moment de l'import (ex: scan déclenché à l'instant). Il n'y a pas de liste de fichiers préexistants.
| Action | Permission | Description |
|---|---|---|
SourceBackendActionGenerateFileDocumentUpload |
document_create |
Nouveau document depuis le fichier généré |
SourceBackendActionGenerateFileDocumentFileUpload |
document_file_new |
Nouvelle version depuis le fichier généré |
source_interactive — Mixin interactifMixin pour les sources où l'utilisateur est présent pendant l'import. S'oppose à source_periodic (automatique).
| Action | Description |
|---|---|
SourceBackendActionInteractiveDocumentUpload |
Upload d'un nouveau document |
SourceBackendActionInteractiveDocumentFileUpload |
Upload d'une nouvelle version |
source_periodic — Mixin automatique (planifié)Mixin pour les sources qui tournent sans intervention humaine. Crée automatiquement une tâche django-celery-beat à la création de la source.
| Champ | Default | Description |
|---|---|---|
document_type_id |
requis | Type de document assigné aux imports |
language |
langue Django | Langue des documents importés |
interval |
3600 s | Intervalle entre deux vérifications (secondes) |
Source créée → IntervalSchedule.get_or_create(every=interval)
→ PeriodicTask.create(name="check_interval_source-{id}")
Source modifiée → delete_periodic_task() → create()
Source supprimée → delete_periodic_task()
→ IntervalSchedule supprimé si plus utilisé
source_sane_scanners — Scanner SANEIntègre un scanner physique compatible SANE via scanimage. Source interactive qui génère le fichier au moment de l'action.
SourceBackendSANEScanner ← SourceBackendMixinInteractive ← SourceBackend
| Champ | Description |
|---|---|
device_name |
Nom du scanner (scanimage --list-devices) |
arguments |
Arguments YAML passés à scanimage |
scanimage --device-name=<device> --format=tiff [args]# Exemple d'arguments YAML
--resolution: 300
--mode: Color
--source: 'Automatic Document Feeder'
source_staging_folders — Dossier de staging (filesystem)Affiche les fichiers d'un dossier local que l'utilisateur choisit d'importer. Les fichiers sont conservés jusqu'à suppression explicite.
SourceBackendStagingFolder
← SourceBackendMixinCompressed
← SourceBackendMixinStoredFileLocationFilesystem
← SourceBackendMixinInteractive
← SourceBackendMixinRegularExpression
← SourceBackendMixinStoredFileInteractive
← SourceBackend
| Champ | Description |
|---|---|
folder_path |
Chemin absolu du dossier sur le serveur |
include_regex |
Filtre inclusif sur le nom de fichier |
exclude_regex |
Filtre exclusif sur le nom de fichier |
uncompress |
Gestion des archives |
source_staging_storages — Dossier de staging (storage backend)Identique à source_staging_folders mais le dossier est défini via un storage backend Django (S3, GCS, etc.) plutôt qu'un chemin local.
SourceBackendStagingStorage
← SourceBackendMixinCompressed
← SourceBackendMixinInteractive
← SourceBackendMixinRegularExpression
← SourceBackendMixinStoredFileInteractive
← SourceBackendMixinStoredFileLocationStorageBackend
← SourceBackend
| Champ | Description |
|---|---|
storage_backend |
Classe Python du storage backend Django |
storage_backend_arguments |
Arguments YAML passés au storage backend |
source_stored_files — Fichiers stockés (base)Bibliothèque de mixins partagée par source_staging_* et source_watch_*. Fournit l'abstraction SourceStoredFile et les mixins de localisation, listage, aperçu et suppression.
SourceStoredFileReprésente un fichier dans une source. Attributs :
filename — nom du fichierencoded_filename — base64 URL-safe (pour les URLs)source — référence à la source| Mixin | Rôle |
|---|---|
SourceBackendMixinStoredFileLocationFilesystem |
Localisation sur le filesystem |
SourceBackendMixinStoredFileLocationStorageBackend |
Localisation via Django storage |
SourceBackendMixinStoredFileList |
Lister les fichiers disponibles |
SourceBackendMixinStoredFileImage |
Générer des aperçus (thumbnail) |
SourceBackendMixinStoredFileDocumentUpload |
Action upload nouveau document |
SourceBackendMixinStoredFileDocumentFileUpload |
Action upload nouvelle version |
SourceBackendMixinStoredFileDeleteInteractive |
Suppression manuelle |
SourceBackendMixinStoredFileDeleteInteractiveNot |
Suppression automatique post-import |
source_watch_folders — Dossier surveillé (filesystem)Surveille un dossier local et importe automatiquement tout nouveau fichier à intervalles réguliers. Les fichiers sont supprimés après import.
SourceBackendWatchFolder
← SourceBackendMixinStoredFileLocationFilesystem
← SourceBackendMixinPeriodicCompressed
← SourceBackendMixinRegularExpression
← SourceBackendMixinStoredFileInteractiveNot
← SourceBackend
| Staging Folder | Watch Folder | |
|---|---|---|
| Déclenchement | Interactif (utilisateur) | Automatique (Celery) |
| Fichier après import | Conservé | Supprimé automatiquement |
| Sélection | L'utilisateur choisit | random.choice parmi les fichiers |
| Aperçu | Oui | Non |
source_watch_storages — Dossier surveillé (storage backend)Identique à source_watch_folders mais utilise un storage backend Django comme localisation.
SourceBackendWatchStorage
← SourceBackendMixinStoredFileLocationStorageBackend
← SourceBackendMixinPeriodicCompressed
← SourceBackendMixinRegularExpression
← SourceBackendMixinStoredFileInteractiveNot
← SourceBackend
source_web_forms — Formulaire web HTML5Source interactive la plus simple : l'utilisateur glisse-dépose ou sélectionne des fichiers depuis son navigateur via un formulaire HTML5 avec drag-and-drop (Dropzone.js).
SourceBackendWebForm
← SourceBackendMixinCompressed
← SourceBackendMixinInteractive
← SourceBackend
Aucun champ supplémentaire au-delà de label, enabled et uncompress.
Mixin Sources qui l'utilisent
──────────────────────────────────────── ──────────────────────────────────────
SourceBackendMixinInteractive WebForm, StagingFolder, StagingStorage, SANE
SourceBackendMixinPeriodic WatchFolder, WatchStorage, IMAP, POP3
SourceBackendMixinCompressed WebForm, StagingFolder, StagingStorage,
WatchFolder, WatchStorage, IMAP, POP3
SourceBackendMixinRegularExpression StagingFolder, StagingStorage,
WatchFolder, WatchStorage
SourceBackendMixinStoredFileInteractive StagingFolder, StagingStorage
SourceBackendMixinStoredFileInteractiveNot WatchFolder, WatchStorage, IMAP, POP3
...LocationFilesystem StagingFolder, WatchFolder
...LocationStorageBackend StagingStorage, WatchStorage
Qui importe ?
├── L'utilisateur (interactif)
│ ├── Depuis son ordinateur → Web Form
│ ├── Depuis un dossier partagé → Staging Folder / Staging Storage
│ └── Depuis un scanner physique → SANE Scanner
│
└── Le système automatiquement (périodique)
├── Depuis un dossier local → Watch Folder
├── Depuis un storage S3/GCS/etc. → Watch Storage
└── Depuis une boîte email → IMAP / POP3
Base : /api/v4/sources/
| Méthode | Endpoint | Permission | Description |
|---|---|---|---|
GET |
/sources/ |
sources_view |
Lister les sources |
POST |
/sources/ |
sources_create |
Créer une source |
GET |
/sources/<id>/ |
sources_view |
Détails |
PATCH/PUT |
/sources/<id>/ |
sources_edit |
Modifier |
DELETE |
/sources/<id>/ |
sources_delete |
Supprimer |
POST |
/sources/<id>/actions/<action>/ |
Selon action | Exécuter une action |