Update the file caching app
- Add view to list available caches. - Add links to view and purge caches. - Add permissions. - Add events. - Add purge task. - Remove document image clear link and view. This is now handled by the file caching app. Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
This commit is contained in:
@@ -61,6 +61,8 @@
|
|||||||
regardless of MIME type.
|
regardless of MIME type.
|
||||||
- Remove task inspection from task manager app.
|
- Remove task inspection from task manager app.
|
||||||
- Move pagination navigation inside the toolbar.
|
- Move pagination navigation inside the toolbar.
|
||||||
|
- Remove document image clear link and view.
|
||||||
|
This is now handled by the file caching app.
|
||||||
|
|
||||||
3.2.6 (2019-07-10)
|
3.2.6 (2019-07-10)
|
||||||
==================
|
==================
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ Changes
|
|||||||
- Add platform template to return queues for a worker.
|
- Add platform template to return queues for a worker.
|
||||||
- Remove task inspection from task manager app.
|
- Remove task inspection from task manager app.
|
||||||
- Move pagination navigation inside the toolbar.
|
- Move pagination navigation inside the toolbar.
|
||||||
|
- Remove document image clear link and view.
|
||||||
|
This is now handled by the file caching app.
|
||||||
|
|
||||||
|
|
||||||
Removals
|
Removals
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ from .handlers import (
|
|||||||
handler_remove_empty_duplicates_lists, handler_scan_duplicates_for
|
handler_remove_empty_duplicates_lists, handler_scan_duplicates_for
|
||||||
)
|
)
|
||||||
from .links import (
|
from .links import (
|
||||||
link_clear_image_cache, link_document_clear_transformations,
|
link_document_clear_transformations,
|
||||||
link_document_clone_transformations, link_document_delete,
|
link_document_clone_transformations, link_document_delete,
|
||||||
link_document_document_type_edit, link_document_download,
|
link_document_document_type_edit, link_document_download,
|
||||||
link_document_duplicates_list, link_document_edit,
|
link_document_duplicates_list, link_document_edit,
|
||||||
@@ -377,7 +377,7 @@ class DocumentsApp(MayanAppConfig):
|
|||||||
|
|
||||||
menu_setup.bind_links(links=(link_document_type_setup,))
|
menu_setup.bind_links(links=(link_document_type_setup,))
|
||||||
menu_tools.bind_links(
|
menu_tools.bind_links(
|
||||||
links=(link_clear_image_cache, link_duplicated_document_scan)
|
links=(link_duplicated_document_scan,)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Document type links
|
# Document type links
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ icon_document_type = Icon(
|
|||||||
|
|
||||||
icon_menu_documents = Icon(driver_name='fontawesome', symbol='book')
|
icon_menu_documents = Icon(driver_name='fontawesome', symbol='book')
|
||||||
|
|
||||||
icon_clear_image_cache = Icon(driver_name='fontawesome', symbol='file-image')
|
|
||||||
|
|
||||||
icon_dashboard_document_types = icon_document_type
|
icon_dashboard_document_types = icon_document_type
|
||||||
icon_dashboard_documents_in_trash = Icon(
|
icon_dashboard_documents_in_trash = Icon(
|
||||||
driver_name='fontawesome', symbol='trash-alt'
|
driver_name='fontawesome', symbol='trash-alt'
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from mayan.apps.converter.permissions import (
|
|||||||
from mayan.apps.navigation.classes import Link
|
from mayan.apps.navigation.classes import Link
|
||||||
|
|
||||||
from .icons import (
|
from .icons import (
|
||||||
icon_clear_image_cache, icon_document_list_recent_access,
|
icon_document_list_recent_access,
|
||||||
icon_recent_added_document_list, icon_document_page_navigation_first,
|
icon_recent_added_document_list, icon_document_page_navigation_first,
|
||||||
icon_document_page_navigation_last, icon_document_page_navigation_next,
|
icon_document_page_navigation_last, icon_document_page_navigation_next,
|
||||||
icon_document_page_navigation_previous, icon_document_page_return,
|
icon_document_page_navigation_previous, icon_document_page_return,
|
||||||
@@ -264,16 +264,6 @@ link_document_list_deleted = Link(
|
|||||||
text=_('Trash can'), view='documents:document_list_deleted'
|
text=_('Trash can'), view='documents:document_list_deleted'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Tools
|
|
||||||
link_clear_image_cache = Link(
|
|
||||||
icon_class=icon_clear_image_cache,
|
|
||||||
description=_(
|
|
||||||
'Clear the graphics representations used to speed up the documents\' '
|
|
||||||
'display and interactive transformations results.'
|
|
||||||
), permissions=(permission_document_tools,),
|
|
||||||
text=_('Clear document image cache'),
|
|
||||||
view='documents:document_clear_image_cache'
|
|
||||||
)
|
|
||||||
link_trash_can_empty = Link(
|
link_trash_can_empty = Link(
|
||||||
permissions=(permission_empty_trash,), text=_('Empty trash'),
|
permissions=(permission_empty_trash,), text=_('Empty trash'),
|
||||||
view='documents:trash_can_empty'
|
view='documents:trash_can_empty'
|
||||||
|
|||||||
@@ -61,10 +61,6 @@ queue_documents_periodic.add_task_type(
|
|||||||
schedule=timedelta(seconds=DELETE_STALE_STUBS_INTERVAL),
|
schedule=timedelta(seconds=DELETE_STALE_STUBS_INTERVAL),
|
||||||
)
|
)
|
||||||
|
|
||||||
queue_tools.add_task_type(
|
|
||||||
dotted_path='mayan.apps.documents.tasks.task_clear_image_cache',
|
|
||||||
label=_('Clear image cache')
|
|
||||||
)
|
|
||||||
queue_tools.add_task_type(
|
queue_tools.add_task_type(
|
||||||
dotted_path='mayan.apps.documents.tasks.task_scan_duplicates_all',
|
dotted_path='mayan.apps.documents.tasks.task_scan_duplicates_all',
|
||||||
label=_('Duplicated document scan')
|
label=_('Duplicated document scan')
|
||||||
|
|||||||
@@ -41,17 +41,6 @@ def task_check_trash_periods():
|
|||||||
DocumentType.objects.check_trash_periods()
|
DocumentType.objects.check_trash_periods()
|
||||||
|
|
||||||
|
|
||||||
@app.task(ignore_result=True)
|
|
||||||
def task_clear_image_cache():
|
|
||||||
Document = apps.get_model(
|
|
||||||
app_label='documents', model_name='Document'
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info('Starting document cache invalidation')
|
|
||||||
Document.objects.invalidate_cache()
|
|
||||||
logger.info('Finished document cache invalidation')
|
|
||||||
|
|
||||||
|
|
||||||
@app.task(ignore_result=True)
|
@app.task(ignore_result=True)
|
||||||
def task_delete_document(trashed_document_id):
|
def task_delete_document(trashed_document_id):
|
||||||
DeletedDocument = apps.get_model(
|
DeletedDocument = apps.get_model(
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from .api_views import (
|
|||||||
APIRecentDocumentListView
|
APIRecentDocumentListView
|
||||||
)
|
)
|
||||||
from .views import (
|
from .views import (
|
||||||
ClearImageCacheView, DocumentDocumentTypeEditView, DocumentDownloadFormView,
|
DocumentDocumentTypeEditView, DocumentDownloadFormView,
|
||||||
DocumentDownloadView, DocumentDuplicatesListView, DocumentEditView,
|
DocumentDownloadView, DocumentDuplicatesListView, DocumentEditView,
|
||||||
DocumentListView, DocumentPageListView, DocumentPageNavigationFirst,
|
DocumentListView, DocumentPageListView, DocumentPageNavigationFirst,
|
||||||
DocumentPageNavigationLast, DocumentPageNavigationNext,
|
DocumentPageNavigationLast, DocumentPageNavigationNext,
|
||||||
@@ -272,10 +272,6 @@ urlpatterns = [
|
|||||||
view=DocumentTransformationsClearView.as_view(),
|
view=DocumentTransformationsClearView.as_view(),
|
||||||
name='document_multiple_clear_transformations'
|
name='document_multiple_clear_transformations'
|
||||||
),
|
),
|
||||||
url(
|
|
||||||
regex=r'^cache/clear/$', view=ClearImageCacheView.as_view(),
|
|
||||||
name='document_clear_image_cache'
|
|
||||||
),
|
|
||||||
url(
|
url(
|
||||||
regex=r'^page/(?P<pk>\d+)/$', view=DocumentPageView.as_view(),
|
regex=r'^page/(?P<pk>\d+)/$', view=DocumentPageView.as_view(),
|
||||||
name='document_page_view'
|
name='document_page_view'
|
||||||
|
|||||||
@@ -8,25 +8,12 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
from mayan.apps.common.generics import ConfirmView
|
from mayan.apps.common.generics import ConfirmView
|
||||||
|
|
||||||
from ..permissions import permission_document_tools
|
from ..permissions import permission_document_tools
|
||||||
from ..tasks import task_clear_image_cache, task_scan_duplicates_all
|
from ..tasks import task_scan_duplicates_all
|
||||||
|
|
||||||
__all__ = ('ClearImageCacheView', 'ScanDuplicatedDocuments')
|
__all__ = ('ScanDuplicatedDocuments',)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ClearImageCacheView(ConfirmView):
|
|
||||||
extra_context = {
|
|
||||||
'title': _('Clear the document image cache?')
|
|
||||||
}
|
|
||||||
view_permission = permission_document_tools
|
|
||||||
|
|
||||||
def view_action(self):
|
|
||||||
task_clear_image_cache.apply_async()
|
|
||||||
messages.success(
|
|
||||||
self.request, _('Document cache clearing queued successfully.')
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ScanDuplicatedDocuments(ConfirmView):
|
class ScanDuplicatedDocuments(ConfirmView):
|
||||||
extra_context = {
|
extra_context = {
|
||||||
'title': _('Scan for duplicated documents?')
|
'title': _('Scan for duplicated documents?')
|
||||||
|
|||||||
@@ -1,8 +1,79 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from mayan.apps.acls.classes import ModelPermission
|
||||||
|
from mayan.apps.acls.links import link_acl_list
|
||||||
|
from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
|
||||||
from mayan.apps.common.apps import MayanAppConfig
|
from mayan.apps.common.apps import MayanAppConfig
|
||||||
|
from mayan.apps.common.menus import (
|
||||||
|
menu_list_facet, menu_multi_item, menu_object, menu_secondary, menu_tools
|
||||||
|
)
|
||||||
|
from mayan.apps.events.classes import ModelEventType
|
||||||
|
from mayan.apps.events.links import (
|
||||||
|
link_events_for_object, link_object_event_types_user_subcriptions_list
|
||||||
|
)
|
||||||
|
from mayan.apps.navigation.classes import SourceColumn
|
||||||
|
|
||||||
|
from .events import event_cache_edited, event_cache_purged
|
||||||
|
from .links import (
|
||||||
|
link_caches_list, link_cache_multiple_purge, link_cache_purge
|
||||||
|
)
|
||||||
|
from .permissions import permission_cache_purge, permission_cache_view
|
||||||
|
|
||||||
|
|
||||||
class FileCachingConfig(MayanAppConfig):
|
class FileCachingConfig(MayanAppConfig):
|
||||||
|
app_namespace = 'file_caching'
|
||||||
|
app_url = 'file_caching'
|
||||||
has_tests = False
|
has_tests = False
|
||||||
name = 'mayan.apps.file_caching'
|
name = 'mayan.apps.file_caching'
|
||||||
|
verbose_name = _('File caching')
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
super(FileCachingConfig, self).ready()
|
||||||
|
from actstream import registry
|
||||||
|
|
||||||
|
Cache = self.get_model(model_name='Cache')
|
||||||
|
|
||||||
|
ModelEventType.register(
|
||||||
|
event_types=(event_cache_edited, event_cache_purged,),
|
||||||
|
model=Cache
|
||||||
|
)
|
||||||
|
|
||||||
|
ModelPermission.register(
|
||||||
|
model=Cache, permissions=(
|
||||||
|
permission_acl_edit, permission_acl_view,
|
||||||
|
permission_cache_purge, permission_cache_view
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
SourceColumn(attribute='name', source=Cache)
|
||||||
|
SourceColumn(attribute='label', source=Cache)
|
||||||
|
SourceColumn(attribute='storage_instance_path', source=Cache)
|
||||||
|
SourceColumn(attribute='get_maximum_size_display', source=Cache)
|
||||||
|
SourceColumn(attribute='get_total_size_display', source=Cache)
|
||||||
|
|
||||||
|
menu_list_facet.bind_links(
|
||||||
|
links=(
|
||||||
|
link_acl_list, link_events_for_object,
|
||||||
|
link_object_event_types_user_subcriptions_list,
|
||||||
|
), sources=(Cache,)
|
||||||
|
)
|
||||||
|
|
||||||
|
menu_object.bind_links(
|
||||||
|
links=(link_cache_purge,),
|
||||||
|
sources=(Cache,)
|
||||||
|
)
|
||||||
|
menu_multi_item.bind_links(
|
||||||
|
links=(link_cache_multiple_purge,),
|
||||||
|
sources=(Cache,)
|
||||||
|
)
|
||||||
|
menu_secondary.bind_links(
|
||||||
|
links=(link_caches_list,), sources=(
|
||||||
|
Cache,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
menu_tools.bind_links(links=(link_caches_list,))
|
||||||
|
|
||||||
|
registry.register(Cache)
|
||||||
|
|||||||
19
mayan/apps/file_caching/events.py
Normal file
19
mayan/apps/file_caching/events.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from mayan.apps.events.classes import EventTypeNamespace
|
||||||
|
|
||||||
|
namespace = EventTypeNamespace(
|
||||||
|
label=_('File caching'), name='file_caching'
|
||||||
|
)
|
||||||
|
|
||||||
|
event_cache_created = namespace.add_event_type(
|
||||||
|
label=_('Cache created'), name='cache_created'
|
||||||
|
)
|
||||||
|
event_cache_edited = namespace.add_event_type(
|
||||||
|
label=_('Cache edited'), name='cache_edited'
|
||||||
|
)
|
||||||
|
event_cache_purged = namespace.add_event_type(
|
||||||
|
label=_('Cache purge'), name='cache_purged'
|
||||||
|
)
|
||||||
11
mayan/apps/file_caching/icons.py
Normal file
11
mayan/apps/file_caching/icons.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
from mayan.apps.appearance.classes import Icon
|
||||||
|
|
||||||
|
icon_file_caching = Icon(
|
||||||
|
driver_name='fontawesome', symbol='warehouse'
|
||||||
|
)
|
||||||
|
icon_cache_purge = Icon(
|
||||||
|
driver_name='fontawesome-dual', primary_symbol='warehouse',
|
||||||
|
secondary_symbol='check'
|
||||||
|
)
|
||||||
22
mayan/apps/file_caching/links.py
Normal file
22
mayan/apps/file_caching/links.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from mayan.apps.navigation.classes import Link
|
||||||
|
|
||||||
|
from .icons import icon_cache_purge, icon_file_caching
|
||||||
|
from .permissions import permission_cache_purge, permission_cache_view
|
||||||
|
|
||||||
|
link_caches_list = Link(
|
||||||
|
icon_class=icon_file_caching, permissions=(permission_cache_view,),
|
||||||
|
text=_('File caches'), view='file_caching:cache_list'
|
||||||
|
)
|
||||||
|
link_cache_purge = Link(
|
||||||
|
icon_class=icon_cache_purge, kwargs={'cache_id': 'resolved_object.id'},
|
||||||
|
permissions=(permission_cache_purge,), text=_('Purge cache'),
|
||||||
|
view='file_caching:cache_purge'
|
||||||
|
)
|
||||||
|
link_cache_multiple_purge = Link(
|
||||||
|
icon_class=icon_cache_purge, text=_('Purge cache'),
|
||||||
|
view='file_caching:cache_multiple_purge'
|
||||||
|
)
|
||||||
@@ -6,6 +6,7 @@ import logging
|
|||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
from django.db.models import Sum
|
from django.db.models import Sum
|
||||||
|
from django.template.defaultfilters import filesizeformat
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.module_loading import import_string
|
from django.utils.module_loading import import_string
|
||||||
@@ -14,18 +15,31 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
from mayan.apps.lock_manager.exceptions import LockError
|
from mayan.apps.lock_manager.exceptions import LockError
|
||||||
from mayan.apps.lock_manager.runtime import locking_backend
|
from mayan.apps.lock_manager.runtime import locking_backend
|
||||||
|
|
||||||
|
from .events import (
|
||||||
|
event_cache_created, event_cache_edited, event_cache_purged
|
||||||
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Cache(models.Model):
|
class Cache(models.Model):
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=128, unique=True, verbose_name=_('Name')
|
help_text=_('Internal name of the cache.'), max_length=128,
|
||||||
|
unique=True, verbose_name=_('Name')
|
||||||
|
)
|
||||||
|
label = models.CharField(
|
||||||
|
help_text=_('A short text describing the cache.'), max_length=128,
|
||||||
|
verbose_name=_('Label')
|
||||||
|
)
|
||||||
|
maximum_size = models.PositiveIntegerField(
|
||||||
|
help_text=_('Maximum size of the cache in bytes.'),
|
||||||
|
verbose_name=_('Maximum size')
|
||||||
)
|
)
|
||||||
label = models.CharField(max_length=128, verbose_name=_('Label'))
|
|
||||||
maximum_size = models.PositiveIntegerField(verbose_name=_('Maximum size'))
|
|
||||||
storage_instance_path = models.CharField(
|
storage_instance_path = models.CharField(
|
||||||
max_length=255, unique=True, verbose_name=_('Storage instance path')
|
help_text=_(
|
||||||
|
'Dotted path to the actual storage class used for the cache.'
|
||||||
|
), max_length=255, unique=True, verbose_name=_('Storage instance path')
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@@ -38,21 +52,55 @@ class Cache(models.Model):
|
|||||||
def get_files(self):
|
def get_files(self):
|
||||||
return CachePartitionFile.objects.filter(partition__cache__id=self.pk)
|
return CachePartitionFile.objects.filter(partition__cache__id=self.pk)
|
||||||
|
|
||||||
|
def get_maximum_size_display(self):
|
||||||
|
return filesizeformat(bytes_=self.maximum_size)
|
||||||
|
|
||||||
|
get_maximum_size_display.short_description = _('Maximum size')
|
||||||
|
|
||||||
def get_total_size(self):
|
def get_total_size(self):
|
||||||
|
"""
|
||||||
|
Return the actual usage of the cache.
|
||||||
|
"""
|
||||||
return self.get_files().aggregate(
|
return self.get_files().aggregate(
|
||||||
file_size__sum=Sum('file_size')
|
file_size__sum=Sum('file_size')
|
||||||
)['file_size__sum'] or 0
|
)['file_size__sum'] or 0
|
||||||
|
|
||||||
|
def get_total_size_display(self):
|
||||||
|
return filesizeformat(bytes_=self.get_total_size())
|
||||||
|
|
||||||
|
get_total_size_display.short_description = _('Total size')
|
||||||
|
|
||||||
def prune(self):
|
def prune(self):
|
||||||
|
"""
|
||||||
|
Deletes files until the total size of the cache is below the allowed
|
||||||
|
maximum size of the cache.
|
||||||
|
"""
|
||||||
while self.get_total_size() > self.maximum_size:
|
while self.get_total_size() > self.maximum_size:
|
||||||
self.get_files().earliest().delete()
|
self.get_files().earliest().delete()
|
||||||
|
|
||||||
def purge(self):
|
def purge(self, _user=None):
|
||||||
|
"""
|
||||||
|
Deletes the entire cache.
|
||||||
|
"""
|
||||||
for partition in self.partitions.all():
|
for partition in self.partitions.all():
|
||||||
partition.purge()
|
partition.purge()
|
||||||
|
|
||||||
|
event_cache_purged.commit(actor=_user, target=self)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
_user = kwargs.pop('_user', None)
|
||||||
|
with transaction.atomic():
|
||||||
|
is_new = not self.pk
|
||||||
result = super(Cache, self).save(*args, **kwargs)
|
result = super(Cache, self).save(*args, **kwargs)
|
||||||
|
if is_new:
|
||||||
|
event_cache_created.commit(
|
||||||
|
actor=_user, target=self
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
event_cache_edited.commit(
|
||||||
|
actor=_user, target=self
|
||||||
|
)
|
||||||
|
|
||||||
self.prune()
|
self.prune()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|||||||
14
mayan/apps/file_caching/permissions.py
Normal file
14
mayan/apps/file_caching/permissions.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from mayan.apps.permissions import PermissionNamespace
|
||||||
|
|
||||||
|
namespace = PermissionNamespace(label=_('File caching'), name='file_caching')
|
||||||
|
|
||||||
|
permission_cache_purge = namespace.add_permission(
|
||||||
|
label=_('Purge a file cache'), name='file_caching_cache_purge'
|
||||||
|
)
|
||||||
|
permission_cache_view = namespace.add_permission(
|
||||||
|
label=_('View a file cache'), name='file_caching_cache_view'
|
||||||
|
)
|
||||||
10
mayan/apps/file_caching/queues.py
Normal file
10
mayan/apps/file_caching/queues.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from mayan.apps.common.queues import queue_tools
|
||||||
|
|
||||||
|
queue_tools.add_task_type(
|
||||||
|
dotted_path='mayan.apps.file_caching.tasks.task_cache_purge',
|
||||||
|
label=_('Purge a file cache')
|
||||||
|
)
|
||||||
25
mayan/apps/file_caching/tasks.py
Normal file
25
mayan/apps/file_caching/tasks.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from django.apps import apps
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
|
from mayan.celery import app
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@app.task(ignore_result=True)
|
||||||
|
def task_cache_purge(cache_id, user_id=None):
|
||||||
|
Cache = apps.get_model(
|
||||||
|
app_label='file_caching', model_name='Cache'
|
||||||
|
)
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
|
cache = Cache.objects.get(pk=cache_id)
|
||||||
|
user = User.objects.get(pk=user_id)
|
||||||
|
|
||||||
|
logger.info('Starting cache id %s purge', cache)
|
||||||
|
cache.purge(_user=user)
|
||||||
|
logger.info('Finished cache id %s purge', cache)
|
||||||
20
mayan/apps/file_caching/urls.py
Normal file
20
mayan/apps/file_caching/urls.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from .views import CacheListView, CachePurgeView
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(
|
||||||
|
regex=r'^caches/$',
|
||||||
|
name='cache_list', view=CacheListView.as_view()
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
regex=r'^caches/(?P<cache_id>\d+)/purge/$',
|
||||||
|
name='cache_purge', view=CachePurgeView.as_view()
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
regex=r'^caches/multiple/purge/$', name='cache_multiple_purge',
|
||||||
|
view=CachePurgeView.as_view()
|
||||||
|
),
|
||||||
|
]
|
||||||
53
mayan/apps/file_caching/views.py
Normal file
53
mayan/apps/file_caching/views.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from django.utils.translation import ungettext
|
||||||
|
|
||||||
|
from mayan.apps.common.generics import (
|
||||||
|
MultipleObjectConfirmActionView, SingleObjectListView
|
||||||
|
)
|
||||||
|
|
||||||
|
from .models import Cache
|
||||||
|
from .permissions import permission_cache_purge, permission_cache_view
|
||||||
|
|
||||||
|
from .tasks import task_cache_purge
|
||||||
|
|
||||||
|
|
||||||
|
class CacheListView(SingleObjectListView):
|
||||||
|
model = Cache
|
||||||
|
permission = permission_cache_view
|
||||||
|
|
||||||
|
def get_extra_context(self):
|
||||||
|
return {
|
||||||
|
'hide_object': True,
|
||||||
|
'title': _('File caches list')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class CachePurgeView(MultipleObjectConfirmActionView):
|
||||||
|
model = Cache
|
||||||
|
object_permission = permission_cache_purge
|
||||||
|
pk_url_kwarg = 'cache_id'
|
||||||
|
success_message_singular = '%(count)d cache submitted for purging.'
|
||||||
|
success_message_plural = '%(count)d caches submitted for purging.'
|
||||||
|
|
||||||
|
def get_extra_context(self):
|
||||||
|
queryset = self.object_list
|
||||||
|
|
||||||
|
result = {
|
||||||
|
'title': ungettext(
|
||||||
|
singular='Submit the selected cache for purging?',
|
||||||
|
plural='Submit the selected caches for purging?',
|
||||||
|
number=queryset.count()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if queryset.count() == 1:
|
||||||
|
result['object'] = queryset.first()
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def object_action(self, form, instance):
|
||||||
|
task_cache_purge.apply_async(
|
||||||
|
kwargs={'cache_id': instance.pk, 'user_id': self.request.user.pk}
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user