From 1ccdd1f4dbf0fa8689f094a46c1345a7673dda80 Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Wed, 5 Nov 2025 17:24:23 -0800
Subject: [PATCH] Consistent naming to Share Link Bundle
---
.../share-bundle-dialog.component.spec.ts | 7 --
...are-bundle-manage-dialog.component.spec.ts | 7 --
.../share-link-bundle-dialog.component.html} | 8 +-
.../share-link-bundle-dialog.component.scss} | 0
...share-link-bundle-dialog.component.spec.ts | 7 ++
.../share-link-bundle-dialog.component.ts} | 40 ++++-----
...-link-bundle-manage-dialog.component.html} | 8 +-
...ink-bundle-manage-dialog.component.spec.ts | 7 ++
...re-link-bundle-manage-dialog.component.ts} | 62 +++++++-------
.../bulk-editor/bulk-editor.component.html | 8 +-
.../bulk-editor/bulk-editor.component.ts | 26 +++---
src-ui/src/app/data/share-bundle.ts | 40 ---------
src-ui/src/app/data/share-link-bundle.ts | 46 ++++++++++
.../app/services/rest/share-bundle.service.ts | 38 ---------
.../rest/share-link-bundle.service.ts | 41 +++++++++
src/documents/admin.py | 6 +-
src/documents/filters.py | 6 +-
...sharebundle.py => 1075_sharelinkbundle.py} | 36 ++++----
src/documents/models.py | 12 +--
src/documents/serialisers.py | 16 ++--
src/documents/tasks.py | 36 ++++----
src/documents/views.py | 85 +++++++++----------
src/paperless/settings.py | 8 +-
src/paperless/urls.py | 4 +-
24 files changed, 283 insertions(+), 271 deletions(-)
delete mode 100644 src-ui/src/app/components/common/share-bundle-dialog/share-bundle-dialog.component.spec.ts
delete mode 100644 src-ui/src/app/components/common/share-bundle-manage-dialog/share-bundle-manage-dialog.component.spec.ts
rename src-ui/src/app/components/common/{share-bundle-dialog/share-bundle-dialog.component.html => share-link-bundle-dialog/share-link-bundle-dialog.component.html} (91%)
rename src-ui/src/app/components/common/{share-bundle-dialog/share-bundle-dialog.component.scss => share-link-bundle-dialog/share-link-bundle-dialog.component.scss} (100%)
create mode 100644 src-ui/src/app/components/common/share-link-bundle-dialog/share-link-bundle-dialog.component.spec.ts
rename src-ui/src/app/components/common/{share-bundle-dialog/share-bundle-dialog.component.ts => share-link-bundle-dialog/share-link-bundle-dialog.component.ts} (73%)
rename src-ui/src/app/components/common/{share-bundle-manage-dialog/share-bundle-manage-dialog.component.html => share-link-bundle-manage-dialog/share-link-bundle-manage-dialog.component.html} (95%)
create mode 100644 src-ui/src/app/components/common/share-link-bundle-manage-dialog/share-link-bundle-manage-dialog.component.spec.ts
rename src-ui/src/app/components/common/{share-bundle-manage-dialog/share-bundle-manage-dialog.component.ts => share-link-bundle-manage-dialog/share-link-bundle-manage-dialog.component.ts} (68%)
delete mode 100644 src-ui/src/app/data/share-bundle.ts
create mode 100644 src-ui/src/app/data/share-link-bundle.ts
delete mode 100644 src-ui/src/app/services/rest/share-bundle.service.ts
create mode 100644 src-ui/src/app/services/rest/share-link-bundle.service.ts
rename src/documents/migrations/{1075_sharebundle.py => 1075_sharelinkbundle.py} (84%)
diff --git a/src-ui/src/app/components/common/share-bundle-dialog/share-bundle-dialog.component.spec.ts b/src-ui/src/app/components/common/share-bundle-dialog/share-bundle-dialog.component.spec.ts
deleted file mode 100644
index baae428ec..000000000
--- a/src-ui/src/app/components/common/share-bundle-dialog/share-bundle-dialog.component.spec.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-describe('ShareBundleDialogComponent', () => {
- it('is pending implementation', () => {
- pending(
- 'ShareBundleDialogComponent tests will be implemented once the dialog logic is finalized.'
- )
- })
-})
diff --git a/src-ui/src/app/components/common/share-bundle-manage-dialog/share-bundle-manage-dialog.component.spec.ts b/src-ui/src/app/components/common/share-bundle-manage-dialog/share-bundle-manage-dialog.component.spec.ts
deleted file mode 100644
index 3f39da1b5..000000000
--- a/src-ui/src/app/components/common/share-bundle-manage-dialog/share-bundle-manage-dialog.component.spec.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-describe('ShareBundleManageDialogComponent', () => {
- it('is pending implementation', () => {
- pending(
- 'ShareBundleManageDialogComponent tests will be implemented once the dialog logic is finalized.'
- )
- })
-})
diff --git a/src-ui/src/app/components/common/share-bundle-dialog/share-bundle-dialog.component.html b/src-ui/src/app/components/common/share-link-bundle-dialog/share-link-bundle-dialog.component.html
similarity index 91%
rename from src-ui/src/app/components/common/share-bundle-dialog/share-bundle-dialog.component.html
rename to src-ui/src/app/components/common/share-link-bundle-dialog/share-link-bundle-dialog.component.html
index 0c9c95bf0..19a6e5d93 100644
--- a/src-ui/src/app/components/common/share-bundle-dialog/share-bundle-dialog.component.html
+++ b/src-ui/src/app/components/common/share-link-bundle-dialog/share-link-bundle-dialog.component.html
@@ -50,9 +50,9 @@
} @else {
-
Share link requested
+
Share link bundle requested
- You can copy the link below or open the management screen to monitor its progress. The link will start working once it is ready.
+ You can copy the share link below or open the manager to monitor progress. The link will start working once the bundle is ready.
@@ -105,11 +105,11 @@
-
- Create a share link
+
+ Create a share link bundle
-
- Manage existing links
+
+ Manage share link bundles
@if (emailEnabled) {
diff --git a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts
index 1e82d612e..69bba8141 100644
--- a/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts
+++ b/src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts
@@ -33,7 +33,7 @@ import {
SelectionDataItem,
} from 'src/app/services/rest/document.service'
import { SavedViewService } from 'src/app/services/rest/saved-view.service'
-import { ShareBundleService } from 'src/app/services/rest/share-bundle.service'
+import { ShareLinkBundleService } from 'src/app/services/rest/share-link-bundle.service'
import { StoragePathService } from 'src/app/services/rest/storage-path.service'
import { TagService } from 'src/app/services/rest/tag.service'
import { SettingsService } from 'src/app/services/settings.service'
@@ -55,8 +55,8 @@ import {
} from '../../common/filterable-dropdown/filterable-dropdown.component'
import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component'
import { PermissionsDialogComponent } from '../../common/permissions-dialog/permissions-dialog.component'
-import { ShareBundleDialogComponent } from '../../common/share-bundle-dialog/share-bundle-dialog.component'
-import { ShareBundleManageDialogComponent } from '../../common/share-bundle-manage-dialog/share-bundle-manage-dialog.component'
+import { ShareLinkBundleDialogComponent } from '../../common/share-link-bundle-dialog/share-link-bundle-dialog.component'
+import { ShareLinkBundleManageDialogComponent } from '../../common/share-link-bundle-manage-dialog/share-link-bundle-manage-dialog.component'
import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
import { CustomFieldsBulkEditDialogComponent } from './custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component'
@@ -90,7 +90,7 @@ export class BulkEditorComponent
private customFieldService = inject(CustomFieldsService)
private permissionService = inject(PermissionsService)
private savedViewService = inject(SavedViewService)
- private shareBundleService = inject(ShareBundleService)
+ private shareLinkBundleService = inject(ShareLinkBundleService)
tagSelectionModel = new FilterableDropdownSelectionModel(true)
correspondentSelectionModel = new FilterableDropdownSelectionModel()
@@ -912,12 +912,12 @@ export class BulkEditorComponent
return this.settings.get(SETTINGS_KEYS.EMAIL_ENABLED)
}
- shareSelected() {
- const modal = this.modalService.open(ShareBundleDialogComponent, {
+ createShareLinkBundle() {
+ const modal = this.modalService.open(ShareLinkBundleDialogComponent, {
backdrop: 'static',
size: 'lg',
})
- const dialog = modal.componentInstance as ShareBundleDialogComponent
+ const dialog = modal.componentInstance as ShareLinkBundleDialogComponent
const selectedDocuments = this.list.documents.filter((d) =>
this.list.selected.has(d.id)
)
@@ -931,7 +931,7 @@ export class BulkEditorComponent
}
dialog.loading = true
dialog.buttonsEnabled = false
- this.shareBundleService
+ this.shareLinkBundleService
.createBundle(payload)
.pipe(first())
.subscribe({
@@ -943,17 +943,17 @@ export class BulkEditorComponent
dialog.payload = null
dialog.onOpenManage = () => {
modal.close()
- this.manageShareLinks()
+ this.manageShareLinkBundles()
}
this.toastService.showInfo(
- $localize`Bulk share link creation requested.`
+ $localize`Share link bundle creation requested.`
)
},
error: (error) => {
dialog.loading = false
dialog.buttonsEnabled = true
this.toastService.showError(
- $localize`Bulk share link creation is not available yet.`,
+ $localize`Share link bundle creation is not available yet.`,
error
)
},
@@ -961,8 +961,8 @@ export class BulkEditorComponent
})
}
- manageShareLinks() {
- const modal = this.modalService.open(ShareBundleManageDialogComponent, {
+ manageShareLinkBundles() {
+ const modal = this.modalService.open(ShareLinkBundleManageDialogComponent, {
backdrop: 'static',
size: 'lg',
})
diff --git a/src-ui/src/app/data/share-bundle.ts b/src-ui/src/app/data/share-bundle.ts
deleted file mode 100644
index 0bd06e53b..000000000
--- a/src-ui/src/app/data/share-bundle.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import { FileVersion } from './share-link'
-
-export enum ShareBundleStatus {
- Pending = 'pending',
- Processing = 'processing',
- Ready = 'ready',
- Failed = 'failed',
-}
-
-export interface ShareBundleSummary {
- id: number
- slug: string
- created: string // Date
- expiration?: string // Date
- documents: number[]
- document_count: number
- file_version: FileVersion
- status: ShareBundleStatus
- built_at?: string
- size_bytes?: number
- last_error?: string
-}
-
-export interface ShareBundleCreatePayload {
- document_ids: number[]
- file_version: FileVersion
- expiration_days: number | null
-}
-
-export const SHARE_BUNDLE_STATUS_LABELS: Record = {
- [ShareBundleStatus.Pending]: $localize`Pending`,
- [ShareBundleStatus.Processing]: $localize`Processing`,
- [ShareBundleStatus.Ready]: $localize`Ready`,
- [ShareBundleStatus.Failed]: $localize`Failed`,
-}
-
-export const SHARE_BUNDLE_FILE_VERSION_LABELS: Record = {
- [FileVersion.Archive]: $localize`Archive`,
- [FileVersion.Original]: $localize`Original`,
-}
diff --git a/src-ui/src/app/data/share-link-bundle.ts b/src-ui/src/app/data/share-link-bundle.ts
new file mode 100644
index 000000000..cdabd1d15
--- /dev/null
+++ b/src-ui/src/app/data/share-link-bundle.ts
@@ -0,0 +1,46 @@
+import { FileVersion } from './share-link'
+
+export enum ShareLinkBundleStatus {
+ Pending = 'pending',
+ Processing = 'processing',
+ Ready = 'ready',
+ Failed = 'failed',
+}
+
+export interface ShareLinkBundleSummary {
+ id: number
+ slug: string
+ created: string // Date
+ expiration?: string // Date
+ documents: number[]
+ document_count: number
+ file_version: FileVersion
+ status: ShareLinkBundleStatus
+ built_at?: string
+ size_bytes?: number
+ last_error?: string
+}
+
+export interface ShareLinkBundleCreatePayload {
+ document_ids: number[]
+ file_version: FileVersion
+ expiration_days: number | null
+}
+
+export const SHARE_LINK_BUNDLE_STATUS_LABELS: Record<
+ ShareLinkBundleStatus,
+ string
+> = {
+ [ShareLinkBundleStatus.Pending]: $localize`Pending`,
+ [ShareLinkBundleStatus.Processing]: $localize`Processing`,
+ [ShareLinkBundleStatus.Ready]: $localize`Ready`,
+ [ShareLinkBundleStatus.Failed]: $localize`Failed`,
+}
+
+export const SHARE_LINK_BUNDLE_FILE_VERSION_LABELS: Record<
+ FileVersion,
+ string
+> = {
+ [FileVersion.Archive]: $localize`Archive`,
+ [FileVersion.Original]: $localize`Original`,
+}
diff --git a/src-ui/src/app/services/rest/share-bundle.service.ts b/src-ui/src/app/services/rest/share-bundle.service.ts
deleted file mode 100644
index 049952199..000000000
--- a/src-ui/src/app/services/rest/share-bundle.service.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Injectable } from '@angular/core'
-import { Observable } from 'rxjs'
-import { map } from 'rxjs/operators'
-import {
- ShareBundleCreatePayload,
- ShareBundleSummary,
-} from 'src/app/data/share-bundle'
-import { AbstractNameFilterService } from './abstract-name-filter-service'
-
-@Injectable({
- providedIn: 'root',
-})
-export class ShareBundleService extends AbstractNameFilterService {
- constructor() {
- super()
- this.resourceName = 'share_bundles'
- }
-
- createBundle(
- payload: ShareBundleCreatePayload
- ): Observable {
- this.clearCache()
- return this.http.post(this.getResourceUrl(), payload)
- }
- rebuildBundle(bundleId: number): Observable {
- this.clearCache()
- return this.http.post(
- this.getResourceUrl(bundleId, 'rebuild'),
- {}
- )
- }
-
- listAllBundles(): Observable {
- return this.list(1, 1000, 'created', true).pipe(
- map((response) => response.results)
- )
- }
-}
diff --git a/src-ui/src/app/services/rest/share-link-bundle.service.ts b/src-ui/src/app/services/rest/share-link-bundle.service.ts
new file mode 100644
index 000000000..2aa719974
--- /dev/null
+++ b/src-ui/src/app/services/rest/share-link-bundle.service.ts
@@ -0,0 +1,41 @@
+import { Injectable } from '@angular/core'
+import { Observable } from 'rxjs'
+import { map } from 'rxjs/operators'
+import {
+ ShareLinkBundleCreatePayload,
+ ShareLinkBundleSummary,
+} from 'src/app/data/share-link-bundle'
+import { AbstractNameFilterService } from './abstract-name-filter-service'
+
+@Injectable({
+ providedIn: 'root',
+})
+export class ShareLinkBundleService extends AbstractNameFilterService {
+ constructor() {
+ super()
+ this.resourceName = 'share_link_bundles'
+ }
+
+ createBundle(
+ payload: ShareLinkBundleCreatePayload
+ ): Observable {
+ this.clearCache()
+ return this.http.post(
+ this.getResourceUrl(),
+ payload
+ )
+ }
+ rebuildBundle(bundleId: number): Observable {
+ this.clearCache()
+ return this.http.post(
+ this.getResourceUrl(bundleId, 'rebuild'),
+ {}
+ )
+ }
+
+ listAllBundles(): Observable {
+ return this.list(1, 1000, 'created', true).pipe(
+ map((response) => response.results)
+ )
+ }
+}
diff --git a/src/documents/admin.py b/src/documents/admin.py
index ca4fe8723..c59e08972 100644
--- a/src/documents/admin.py
+++ b/src/documents/admin.py
@@ -12,8 +12,8 @@ from documents.models import Note
from documents.models import PaperlessTask
from documents.models import SavedView
from documents.models import SavedViewFilterRule
-from documents.models import ShareBundle
from documents.models import ShareLink
+from documents.models import ShareLinkBundle
from documents.models import StoragePath
from documents.models import Tag
from documents.tasks import update_document_parent_tags
@@ -186,7 +186,7 @@ class ShareLinksAdmin(GuardedModelAdmin):
return super().get_queryset(request).select_related("document__correspondent")
-class ShareBundleAdmin(GuardedModelAdmin):
+class ShareLinkBundleAdmin(GuardedModelAdmin):
list_display = ("created", "status", "expiration", "owner", "slug")
list_filter = ("status", "created", "expiration", "owner")
search_fields = ("slug",)
@@ -233,7 +233,7 @@ admin.site.register(StoragePath, StoragePathAdmin)
admin.site.register(PaperlessTask, TaskAdmin)
admin.site.register(Note, NotesAdmin)
admin.site.register(ShareLink, ShareLinksAdmin)
-admin.site.register(ShareBundle, ShareBundleAdmin)
+admin.site.register(ShareLinkBundle, ShareLinkBundleAdmin)
admin.site.register(CustomField, CustomFieldsAdmin)
admin.site.register(CustomFieldInstance, CustomFieldInstancesAdmin)
diff --git a/src/documents/filters.py b/src/documents/filters.py
index 289d49d0d..7b9d8dd4d 100644
--- a/src/documents/filters.py
+++ b/src/documents/filters.py
@@ -38,8 +38,8 @@ from documents.models import CustomFieldInstance
from documents.models import Document
from documents.models import DocumentType
from documents.models import PaperlessTask
-from documents.models import ShareBundle
from documents.models import ShareLink
+from documents.models import ShareLinkBundle
from documents.models import StoragePath
from documents.models import Tag
@@ -794,11 +794,11 @@ class ShareLinkFilterSet(FilterSet):
}
-class ShareBundleFilterSet(FilterSet):
+class ShareLinkBundleFilterSet(FilterSet):
documents = Filter(method="filter_documents")
class Meta:
- model = ShareBundle
+ model = ShareLinkBundle
fields = {
"created": DATETIME_KWARGS,
"expiration": DATETIME_KWARGS,
diff --git a/src/documents/migrations/1075_sharebundle.py b/src/documents/migrations/1075_sharelinkbundle.py
similarity index 84%
rename from src/documents/migrations/1075_sharebundle.py
rename to src/documents/migrations/1075_sharelinkbundle.py
index a64ad29d3..b48eb5ec3 100644
--- a/src/documents/migrations/1075_sharebundle.py
+++ b/src/documents/migrations/1075_sharelinkbundle.py
@@ -11,7 +11,7 @@ from django.db import migrations
from django.db import models
-def grant_sharebundle_permissions(apps, schema_editor):
+def grant_share_link_bundle_permissions(apps, schema_editor):
# Ensure newly introduced permissions are created for all apps
for app_config in apps.get_app_configs():
app_config.models_module = True
@@ -22,27 +22,27 @@ def grant_sharebundle_permissions(apps, schema_editor):
if add_document_perm is None:
return
- sharebundle_permissions = Permission.objects.filter(
- codename__contains="sharebundle",
+ share_bundle_permissions = Permission.objects.filter(
+ codename__contains="sharelinkbundle",
)
users = User.objects.filter(user_permissions=add_document_perm).distinct()
for user in users:
- user.user_permissions.add(*sharebundle_permissions)
+ user.user_permissions.add(*share_bundle_permissions)
groups = Group.objects.filter(permissions=add_document_perm).distinct()
for group in groups:
- group.permissions.add(*sharebundle_permissions)
+ group.permissions.add(*share_bundle_permissions)
-def revoke_sharebundle_permissions(apps, schema_editor):
- sharebundle_permissions = Permission.objects.filter(
- codename__contains="sharebundle",
+def revoke_share_link_bundle_permissions(apps, schema_editor):
+ share_bundle_permissions = Permission.objects.filter(
+ codename__contains="sharelinkbundle",
)
for user in User.objects.all():
- user.user_permissions.remove(*sharebundle_permissions)
+ user.user_permissions.remove(*share_bundle_permissions)
for group in Group.objects.all():
- group.permissions.remove(*sharebundle_permissions)
+ group.permissions.remove(*share_bundle_permissions)
class Migration(migrations.Migration):
@@ -53,7 +53,7 @@ class Migration(migrations.Migration):
operations = [
migrations.CreateModel(
- name="ShareBundle",
+ name="ShareLinkBundle",
fields=[
(
"id",
@@ -150,7 +150,7 @@ class Migration(migrations.Migration):
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
- related_name="share_bundles",
+ related_name="share_link_bundles",
to=settings.AUTH_USER_MODEL,
verbose_name="owner",
),
@@ -170,21 +170,21 @@ class Migration(migrations.Migration):
],
options={
"ordering": ("-created",),
- "verbose_name": "share bundle",
- "verbose_name_plural": "share bundles",
+ "verbose_name": "share link bundle",
+ "verbose_name_plural": "share link bundles",
},
),
migrations.AddField(
- model_name="sharebundle",
+ model_name="sharelinkbundle",
name="documents",
field=models.ManyToManyField(
- related_name="share_bundles",
+ related_name="share_link_bundles",
to="documents.document",
verbose_name="documents",
),
),
migrations.RunPython(
- grant_sharebundle_permissions,
- reverse_code=revoke_sharebundle_permissions,
+ grant_share_link_bundle_permissions,
+ reverse_code=revoke_share_link_bundle_permissions,
),
]
diff --git a/src/documents/models.py b/src/documents/models.py
index 0bd4aedd8..7871983b6 100644
--- a/src/documents/models.py
+++ b/src/documents/models.py
@@ -777,7 +777,7 @@ class ShareLink(SoftDeleteModel):
return f"Share Link for {self.document.title}"
-class ShareBundle(SoftDeleteModel):
+class ShareLinkBundle(SoftDeleteModel):
class Status(models.TextChoices):
PENDING = ("pending", _("Pending"))
PROCESSING = ("processing", _("Processing"))
@@ -786,8 +786,8 @@ class ShareBundle(SoftDeleteModel):
class Meta:
ordering = ("-created",)
- verbose_name = _("share bundle")
- verbose_name_plural = _("share bundles")
+ verbose_name = _("share link bundle")
+ verbose_name_plural = _("share link bundles")
created = models.DateTimeField(
_("created"),
@@ -816,7 +816,7 @@ class ShareBundle(SoftDeleteModel):
User,
blank=True,
null=True,
- related_name="share_bundles",
+ related_name="share_link_bundles",
on_delete=models.SET_NULL,
verbose_name=_("owner"),
)
@@ -858,12 +858,12 @@ class ShareBundle(SoftDeleteModel):
documents = models.ManyToManyField(
"documents.Document",
- related_name="share_bundles",
+ related_name="share_link_bundles",
verbose_name=_("documents"),
)
def __str__(self):
- return _("Share bundle %(slug)s") % {"slug": self.slug}
+ return _("Share link bundle %(slug)s") % {"slug": self.slug}
@property
def absolute_file_path(self) -> Path | None:
diff --git a/src/documents/serialisers.py b/src/documents/serialisers.py
index 5fd3dd0c5..85691a1bc 100644
--- a/src/documents/serialisers.py
+++ b/src/documents/serialisers.py
@@ -58,8 +58,8 @@ from documents.models import Note
from documents.models import PaperlessTask
from documents.models import SavedView
from documents.models import SavedViewFilterRule
-from documents.models import ShareBundle
from documents.models import ShareLink
+from documents.models import ShareLinkBundle
from documents.models import StoragePath
from documents.models import Tag
from documents.models import UiSettings
@@ -2130,7 +2130,7 @@ class ShareLinkSerializer(OwnedObjectSerializer):
return super().create(validated_data)
-class ShareBundleSerializer(OwnedObjectSerializer):
+class ShareLinkBundleSerializer(OwnedObjectSerializer):
document_ids = serializers.ListField(
child=serializers.IntegerField(min_value=1),
allow_empty=False,
@@ -2149,7 +2149,7 @@ class ShareBundleSerializer(OwnedObjectSerializer):
document_count = SerializerMethodField()
class Meta:
- model = ShareBundle
+ model = ShareLinkBundle
fields = (
"id",
"created",
@@ -2198,7 +2198,7 @@ class ShareBundleSerializer(OwnedObjectSerializer):
else:
validated_data["expiration"] = None
- share_bundle = super().create(validated_data)
+ share_link_bundle = super().create(validated_data)
if documents is None:
documents = list(
@@ -2224,12 +2224,12 @@ class ShareBundleSerializer(OwnedObjectSerializer):
)
ordered_documents = [documents_by_id[doc_id] for doc_id in document_ids]
- share_bundle.documents.set(ordered_documents)
- share_bundle.document_total = len(ordered_documents)
+ share_link_bundle.documents.set(ordered_documents)
+ share_link_bundle.document_total = len(ordered_documents)
- return share_bundle
+ return share_link_bundle
- def get_document_count(self, obj: ShareBundle) -> int:
+ def get_document_count(self, obj: ShareLinkBundle) -> int:
count = getattr(obj, "document_total", None)
if count is not None:
return count
diff --git a/src/documents/tasks.py b/src/documents/tasks.py
index 055b3cc59..9dad945c0 100644
--- a/src/documents/tasks.py
+++ b/src/documents/tasks.py
@@ -43,8 +43,8 @@ from documents.models import CustomFieldInstance
from documents.models import Document
from documents.models import DocumentType
from documents.models import PaperlessTask
-from documents.models import ShareBundle
from documents.models import ShareLink
+from documents.models import ShareLinkBundle
from documents.models import StoragePath
from documents.models import Tag
from documents.models import Workflow
@@ -572,17 +572,19 @@ def update_document_parent_tags(tag: Tag, new_parent: Tag) -> None:
@shared_task
-def build_share_bundle(bundle_id: int):
+def build_share_link_bundle(bundle_id: int):
try:
bundle = (
- ShareBundle.objects.filter(pk=bundle_id).prefetch_related("documents").get()
+ ShareLinkBundle.objects.filter(pk=bundle_id)
+ .prefetch_related("documents")
+ .get()
)
- except ShareBundle.DoesNotExist:
- logger.warning("Share bundle %s no longer exists.", bundle_id)
+ except ShareLinkBundle.DoesNotExist:
+ logger.warning("Share link bundle %s no longer exists.", bundle_id)
return
bundle.remove_file()
- bundle.status = ShareBundle.Status.PROCESSING
+ bundle.status = ShareLinkBundle.Status.PROCESSING
bundle.last_error = ""
bundle.size_bytes = None
bundle.built_at = None
@@ -617,7 +619,7 @@ def build_share_bundle(bundle_id: int):
for document in documents:
strategy.add_document(document)
- output_dir = settings.SHARE_BUNDLE_DIR
+ output_dir = settings.SHARE_LINK_BUNDLE_DIR
output_dir.mkdir(parents=True, exist_ok=True)
final_path = (output_dir / f"{bundle.slug}.zip").resolve()
if final_path.exists():
@@ -629,7 +631,7 @@ def build_share_bundle(bundle_id: int):
except ValueError:
bundle.file_path = str(final_path)
bundle.size_bytes = final_path.stat().st_size
- bundle.status = ShareBundle.Status.READY
+ bundle.status = ShareLinkBundle.Status.READY
bundle.built_at = timezone.now()
bundle.last_error = ""
bundle.save(
@@ -641,10 +643,14 @@ def build_share_bundle(bundle_id: int):
"last_error",
],
)
- logger.info("Built share bundle %s", bundle.pk)
+ logger.info("Built share link bundle %s", bundle.pk)
except Exception as exc:
- logger.exception("Failed to build share bundle %s: %s", bundle_id, exc)
- bundle.status = ShareBundle.Status.FAILED
+ logger.exception(
+ "Failed to build share link bundle %s: %s",
+ bundle_id,
+ exc,
+ )
+ bundle.status = ShareLinkBundle.Status.FAILED
bundle.last_error = str(exc)
bundle.save(update_fields=["status", "last_error"])
try:
@@ -661,9 +667,9 @@ def build_share_bundle(bundle_id: int):
@shared_task
-def cleanup_expired_share_bundles():
+def cleanup_expired_share_link_bundles():
now = timezone.now()
- expired_qs = ShareBundle.objects.filter(
+ expired_qs = ShareLinkBundle.objects.filter(
deleted_at__isnull=True,
expiration__isnull=False,
expiration__lt=now,
@@ -675,9 +681,9 @@ def cleanup_expired_share_bundles():
bundle.hard_delete()
except Exception as exc:
logger.warning(
- "Failed to delete expired share bundle %s: %s",
+ "Failed to delete expired share link bundle %s: %s",
bundle.pk,
exc,
)
if count:
- logger.info("Deleted %s expired share bundle(s)", count)
+ logger.info("Deleted %s expired share link bundle(s)", count)
diff --git a/src/documents/views.py b/src/documents/views.py
index 87ae16e26..8817ee15e 100644
--- a/src/documents/views.py
+++ b/src/documents/views.py
@@ -119,7 +119,7 @@ from documents.filters import DocumentTypeFilterSet
from documents.filters import ObjectOwnedOrGrantedPermissionsFilter
from documents.filters import ObjectOwnedPermissionsFilter
from documents.filters import PaperlessTaskFilterSet
-from documents.filters import ShareBundleFilterSet
+from documents.filters import ShareLinkBundleFilterSet
from documents.filters import ShareLinkFilterSet
from documents.filters import StoragePathFilterSet
from documents.filters import TagFilterSet
@@ -135,8 +135,8 @@ from documents.models import DocumentType
from documents.models import Note
from documents.models import PaperlessTask
from documents.models import SavedView
-from documents.models import ShareBundle
from documents.models import ShareLink
+from documents.models import ShareLinkBundle
from documents.models import StoragePath
from documents.models import Tag
from documents.models import UiSettings
@@ -170,7 +170,7 @@ from documents.serialisers import PostDocumentSerializer
from documents.serialisers import RunTaskViewSerializer
from documents.serialisers import SavedViewSerializer
from documents.serialisers import SearchResultSerializer
-from documents.serialisers import ShareBundleSerializer
+from documents.serialisers import ShareLinkBundleSerializer
from documents.serialisers import ShareLinkSerializer
from documents.serialisers import StoragePathSerializer
from documents.serialisers import StoragePathTestSerializer
@@ -183,7 +183,7 @@ from documents.serialisers import WorkflowActionSerializer
from documents.serialisers import WorkflowSerializer
from documents.serialisers import WorkflowTriggerSerializer
from documents.signals import document_updated
-from documents.tasks import build_share_bundle
+from documents.tasks import build_share_link_bundle
from documents.tasks import consume_file
from documents.tasks import empty_trash
from documents.tasks import index_optimize
@@ -2604,12 +2604,12 @@ class ShareLinkViewSet(ModelViewSet, PassUserMixin):
ordering_fields = ("created", "expiration", "document")
-class ShareBundleViewSet(ModelViewSet, PassUserMixin):
- model = ShareBundle
+class ShareLinkBundleViewSet(ModelViewSet, PassUserMixin):
+ model = ShareLinkBundle
- queryset = ShareBundle.objects.all()
+ queryset = ShareLinkBundle.objects.all()
- serializer_class = ShareBundleSerializer
+ serializer_class = ShareLinkBundleSerializer
pagination_class = StandardPagination
permission_classes = (IsAuthenticated, PaperlessObjectPermissions)
filter_backends = (
@@ -2617,7 +2617,7 @@ class ShareBundleViewSet(ModelViewSet, PassUserMixin):
OrderingFilter,
ObjectOwnedOrGrantedPermissionsFilter,
)
- filterset_class = ShareBundleFilterSet
+ filterset_class = ShareLinkBundleFilterSet
ordering_fields = ("created", "expiration", "status")
def get_queryset(self):
@@ -2667,7 +2667,7 @@ class ShareBundleViewSet(ModelViewSet, PassUserMixin):
documents=ordered_documents,
)
bundle.remove_file()
- bundle.status = ShareBundle.Status.PENDING
+ bundle.status = ShareLinkBundle.Status.PENDING
bundle.last_error = ""
bundle.size_bytes = None
bundle.built_at = None
@@ -2681,7 +2681,7 @@ class ShareBundleViewSet(ModelViewSet, PassUserMixin):
"file_path",
],
)
- build_share_bundle.delay(bundle.pk)
+ build_share_link_bundle.delay(bundle.pk)
bundle.document_total = len(ordered_documents)
response_serializer = self.get_serializer(bundle)
headers = self.get_success_headers(response_serializer.data)
@@ -2694,13 +2694,13 @@ class ShareBundleViewSet(ModelViewSet, PassUserMixin):
@action(detail=True, methods=["post"])
def rebuild(self, request, pk=None):
bundle = self.get_object()
- if bundle.status == ShareBundle.Status.PROCESSING:
+ if bundle.status == ShareLinkBundle.Status.PROCESSING:
return Response(
{"detail": _("Bundle is already being processed.")},
status=status.HTTP_400_BAD_REQUEST,
)
bundle.remove_file()
- bundle.status = ShareBundle.Status.PENDING
+ bundle.status = ShareLinkBundle.Status.PENDING
bundle.last_error = ""
bundle.size_bytes = None
bundle.built_at = None
@@ -2714,7 +2714,7 @@ class ShareBundleViewSet(ModelViewSet, PassUserMixin):
"file_path",
],
)
- build_share_bundle.delay(bundle.pk)
+ build_share_link_bundle.delay(bundle.pk)
bundle.document_total = (
getattr(bundle, "document_total", None) or bundle.documents.count()
)
@@ -2740,35 +2740,32 @@ class SharedLinkView(View):
disposition="inline",
)
- share_bundle = ShareBundle.objects.filter(slug=slug).first()
- if share_bundle is None:
+ bundle = ShareLinkBundle.objects.filter(slug=slug).first()
+ if bundle is None:
return HttpResponseRedirect("/accounts/login/?sharelink_notfound=1")
- if (
- share_bundle.expiration is not None
- and share_bundle.expiration < timezone.now()
- ):
+ if bundle.expiration is not None and bundle.expiration < timezone.now():
return HttpResponseRedirect("/accounts/login/?sharelink_expired=1")
- if share_bundle.status in {
- ShareBundle.Status.PENDING,
- ShareBundle.Status.PROCESSING,
+ if bundle.status in {
+ ShareLinkBundle.Status.PENDING,
+ ShareLinkBundle.Status.PROCESSING,
}:
return HttpResponse(
_(
- "The shared bundle is still being prepared. Please try again later.",
+ "The share link bundle is still being prepared. Please try again later.",
),
status=status.HTTP_202_ACCEPTED,
)
- if share_bundle.status == ShareBundle.Status.FAILED:
- share_bundle.remove_file()
- share_bundle.status = ShareBundle.Status.PENDING
- share_bundle.last_error = ""
- share_bundle.size_bytes = None
- share_bundle.built_at = None
- share_bundle.file_path = ""
- share_bundle.save(
+ if bundle.status == ShareLinkBundle.Status.FAILED:
+ bundle.remove_file()
+ bundle.status = ShareLinkBundle.Status.PENDING
+ bundle.last_error = ""
+ bundle.size_bytes = None
+ bundle.built_at = None
+ bundle.file_path = ""
+ bundle.save(
update_fields=[
"status",
"last_error",
@@ -2777,22 +2774,22 @@ class SharedLinkView(View):
"file_path",
],
)
- build_share_bundle.delay(share_bundle.pk)
+ build_share_link_bundle.delay(bundle.pk)
return HttpResponse(
_(
- "The shared bundle is temporarily unavailable. A rebuild has been scheduled. Please try again later.",
+ "The share link bundle is temporarily unavailable. A rebuild has been scheduled. Please try again later.",
),
status=status.HTTP_503_SERVICE_UNAVAILABLE,
)
- file_path = share_bundle.absolute_file_path
+ file_path = bundle.absolute_file_path
if file_path is None or not file_path.exists():
- share_bundle.status = ShareBundle.Status.PENDING
- share_bundle.last_error = ""
- share_bundle.size_bytes = None
- share_bundle.built_at = None
- share_bundle.file_path = ""
- share_bundle.save(
+ bundle.status = ShareLinkBundle.Status.PENDING
+ bundle.last_error = ""
+ bundle.size_bytes = None
+ bundle.built_at = None
+ bundle.file_path = ""
+ bundle.save(
update_fields=[
"status",
"last_error",
@@ -2801,16 +2798,16 @@ class SharedLinkView(View):
"file_path",
],
)
- build_share_bundle.delay(share_bundle.pk)
+ build_share_link_bundle.delay(bundle.pk)
return HttpResponse(
_(
- "The shared bundle is being prepared. Please try again later.",
+ "The share link bundle is being prepared. Please try again later.",
),
status=status.HTTP_202_ACCEPTED,
)
response = FileResponse(file_path.open("rb"), content_type="application/zip")
- short_slug = share_bundle.slug[:12]
+ short_slug = bundle.slug[:12]
download_name = f"paperless-share-{short_slug}.zip"
filename_normalized = (
normalize("NFKD", download_name)
diff --git a/src/paperless/settings.py b/src/paperless/settings.py
index cfcc6692a..425d7462a 100644
--- a/src/paperless/settings.py
+++ b/src/paperless/settings.py
@@ -231,11 +231,11 @@ def _parse_beat_schedule() -> dict:
},
},
{
- "name": "Cleanup expired share bundles",
- "env_key": "PAPERLESS_SHARE_BUNDLE_CLEANUP_CRON",
+ "name": "Cleanup expired share link bundles",
+ "env_key": "PAPERLESS_SHARE_LINK_BUNDLE_CLEANUP_CRON",
# Default daily at 02:00
"env_default": "0 2 * * *",
- "task": "documents.tasks.cleanup_expired_share_bundles",
+ "task": "documents.tasks.cleanup_expired_share_link_bundles",
"options": {
# 1 hour before default schedule sends again
"expires": 23.0 * 60.0 * 60.0,
@@ -279,7 +279,7 @@ MEDIA_ROOT = __get_path("PAPERLESS_MEDIA_ROOT", BASE_DIR.parent / "media")
ORIGINALS_DIR = MEDIA_ROOT / "documents" / "originals"
ARCHIVE_DIR = MEDIA_ROOT / "documents" / "archive"
THUMBNAIL_DIR = MEDIA_ROOT / "documents" / "thumbnails"
-SHARE_BUNDLE_DIR = MEDIA_ROOT / "documents" / "share_bundles"
+SHARE_LINK_BUNDLE_DIR = MEDIA_ROOT / "documents" / "share_link_bundles"
DATA_DIR = __get_path("PAPERLESS_DATA_DIR", BASE_DIR.parent / "data")
diff --git a/src/paperless/urls.py b/src/paperless/urls.py
index 505eb3fa0..2307d939b 100644
--- a/src/paperless/urls.py
+++ b/src/paperless/urls.py
@@ -29,8 +29,8 @@ from documents.views import RemoteVersionView
from documents.views import SavedViewViewSet
from documents.views import SearchAutoCompleteView
from documents.views import SelectionDataView
-from documents.views import ShareBundleViewSet
from documents.views import SharedLinkView
+from documents.views import ShareLinkBundleViewSet
from documents.views import ShareLinkViewSet
from documents.views import StatisticsView
from documents.views import StoragePathViewSet
@@ -73,7 +73,7 @@ api_router.register(r"users", UserViewSet, basename="users")
api_router.register(r"groups", GroupViewSet, basename="groups")
api_router.register(r"mail_accounts", MailAccountViewSet)
api_router.register(r"mail_rules", MailRuleViewSet)
-api_router.register(r"share_bundles", ShareBundleViewSet)
+api_router.register(r"share_link_bundles", ShareLinkBundleViewSet)
api_router.register(r"share_links", ShareLinkViewSet)
api_router.register(r"workflow_triggers", WorkflowTriggerViewSet)
api_router.register(r"workflow_actions", WorkflowActionViewSet)