# HG changeset patch # User Thierry Florac # Date 1464878366 -7200 # Node ID f188db1a1ce7e2302b448b1bc975689fdc9e24ae # Parent 52a07a902854f612befcd2c2817bf4261ce11c13 Added progress functions diff -r 52a07a902854 -r f188db1a1ce7 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 +# 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'])