Added progress functions
authorThierry Florac <thierry.florac@onf.fr>
Thu, 02 Jun 2016 16:39:26 +0200
changeset 63 f188db1a1ce7
parent 62 52a07a902854
child 64 70f2321e267a
Added progress functions
src/pyams_utils/progress.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_utils/progress.py	Thu Jun 02 16:39:26 2016 +0200
@@ -0,0 +1,123 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+from datetime import datetime
+from threading import local
+
+# import interfaces
+
+# import packages
+from beaker import cache
+from pyams_utils.lock import locked
+from pyramid.httpexceptions import HTTPBadRequest
+from pyramid.view import view_config
+
+
+_local = local()
+
+
+def get_tasks_cache():
+    """Get cache storing tasks list"""
+    try:
+        tasks_cache = _local.running_tasks_cache
+    except AttributeError:
+        manager = cache.CacheManager(**cache.cache_regions['persistent'])
+        tasks_cache = _local.running_tasks_cache = manager.get_cache('PyAMS::progress')
+    return tasks_cache
+
+
+def get_progress_cache():
+    """Get cache storing tasks progress"""
+    try:
+        local_cache = _local.progress_cache
+    except AttributeError:
+        manager = cache.CacheManager(**cache.cache_regions['default'])
+        local_cache = _local.progress_cache = manager.get_cache('PyAMS::progress')
+    return local_cache
+
+
+def get_running_tasks():
+    """Get list of running tasks"""
+    tasks_cache = get_tasks_cache()
+    return tasks_cache.get_value('PyAMS_utils::running_tasks', createfunc=set)
+
+
+def set_running_tasks(tasks):
+    """Update list of running tasks"""
+    tasks_cache = get_tasks_cache()
+    tasks_cache.set_value('PyAMS_utils::running_tasks', tasks)
+
+
+@locked(name='progress_status')
+def init_progress_status(progress_id, owner, label, tags=None, length=None, current=None):
+    """Initialize progress status for given task ID"""
+    status = {'status': 'running',
+              'owner': owner,
+              'label': label,
+              'tags': tags,
+              'length': length,
+              'current': current,
+              'started': datetime.utcnow()}
+    # Store task status
+    cache_key = 'PyAMS_task::{0}'.format(progress_id)
+    progress_cache = get_progress_cache()
+    progress_cache.set_value(cache_key, status)
+    # Store task in running tasks list
+    tasks = get_running_tasks()
+    tasks.add(progress_id)
+    set_running_tasks(tasks)
+
+
+@locked(name='progress_status')
+def get_progress_status(progress_id):
+    """Get status of given task"""
+    progress_cache = get_progress_cache()
+    cache_key = 'PyAMS_task::{0}'.format(progress_id)
+    try:
+        status = progress_cache.get_value(cache_key)
+    except KeyError:
+        status = {'status': 'unknown'}
+    else:
+        if status.get('status') == 'finished':
+            progress_cache.remove_value(cache_key)
+            tasks = get_running_tasks()
+            if progress_id in tasks:
+                tasks.remove(progress_id)
+    return status
+
+
+@locked(name='progress_status')
+def set_progress_status(progress_id, status='running', message=None, length=None, current=None):
+    """Set status of given task"""
+    progress_cache = get_progress_cache()
+    cache_key = 'PyAMS_task::{0}'.format(progress_id)
+    try:
+        task_status = progress_cache.get_value(cache_key)
+    except KeyError:
+        task_status = {'status': 'unknown'}
+    task_status.update({'status': status,
+                        'message': message,
+                        'length': length,
+                        'current': current})
+    progress_cache.set_value(cache_key, task_status)
+
+
+@view_config(name='get_progress_status.json', renderer='JSON', xhr=True)
+def get_progress_status_view(request):
+    """Get progress status"""
+    if 'progress_id' not in request.params:
+        raise HTTPBadRequest("Missing argument")
+    return get_progress_status(request.params['progress_id'])