Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-django-rq for openSUSE:Factory checked in at 2023-06-11 19:56:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-django-rq (Old) and /work/SRC/openSUSE:Factory/.python-django-rq.new.15902 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-django-rq" Sun Jun 11 19:56:16 2023 rev:5 rq:1092282 version:2.8.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-django-rq/python-django-rq.changes 2023-05-04 17:11:03.336533958 +0200 +++ /work/SRC/openSUSE:Factory/.python-django-rq.new.15902/python-django-rq.changes 2023-06-11 19:58:53.440466033 +0200 @@ -1,0 +2,8 @@ +Sat May 27 21:30:50 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 2.8.1: + * Added a button to stop currently running jobs. + * Added a failed jobs column to rqstats command. + * Explicitly requires RQ >= 1.14 in `setup.py`. + +------------------------------------------------------------------- Old: ---- django-rq-2.8.0.tar.gz New: ---- django-rq-2.8.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-django-rq.spec ++++++ --- /var/tmp/diff_new_pack.tOFzU4/_old 2023-06-11 19:58:54.096469989 +0200 +++ /var/tmp/diff_new_pack.tOFzU4/_new 2023-06-11 19:58:54.100470013 +0200 @@ -19,7 +19,7 @@ %define skip_python2 1 %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-django-rq -Version: 2.8.0 +Version: 2.8.1 Release: 0 Summary: Simple app that provides django integration for RQ (Redis Queue) License: MIT @@ -30,14 +30,14 @@ BuildRequires: fdupes BuildRequires: python-rpm-macros Requires: python-Django >= 2.0 -Requires: python-rq >= 1.2 +Requires: python-rq >= 1.14 Recommends: python-django-redis >= 3.0 BuildArch: noarch # SECTION test requirements BuildRequires: %{python_module Django >= 2.0} BuildRequires: %{python_module django-redis >= 3.0} BuildRequires: %{python_module pytest-django} -BuildRequires: %{python_module rq >= 1.2} +BuildRequires: %{python_module rq >= 1.14} BuildRequires: redis # /SECTION %python_subpackages ++++++ django-rq-2.8.0.tar.gz -> django-rq-2.8.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-rq-2.8.0/CHANGELOG.md new/django-rq-2.8.1/CHANGELOG.md --- old/django-rq-2.8.0/CHANGELOG.md 2023-05-02 05:18:13.000000000 +0200 +++ new/django-rq-2.8.1/CHANGELOG.md 2023-05-14 03:31:42.000000000 +0200 @@ -1,3 +1,8 @@ +# Version 2.8.1 (2023-05-14) +* Added a button to stop currently running jobs. Thanks @gabriels1234! +* Added a failed jobs column to rqstats command. Thanks @dangquangdon! +* Explicitly requires RQ >= 1.14 in `setup.py`. Thanks @selwin! + # Version 2.8.0 (2023-05-02) * Support for RQ 1.14. Thanks @Cerebro92 and @selwin! * Show scheduler PID information in admin interface. Thanks @gabriels1234! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-rq-2.8.0/django_rq/__init__.py new/django-rq-2.8.1/django_rq/__init__.py --- old/django-rq-2.8.0/django_rq/__init__.py 2023-05-02 05:18:13.000000000 +0200 +++ new/django-rq-2.8.1/django_rq/__init__.py 2023-05-14 03:31:42.000000000 +0200 @@ -1,4 +1,4 @@ -VERSION = (2, 8, 0) +VERSION = (2, 8, 1) from .decorators import job from .queues import enqueue, get_connection, get_queue, get_scheduler diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-rq-2.8.0/django_rq/management/commands/rqstats.py new/django-rq-2.8.1/django_rq/management/commands/rqstats.py --- old/django-rq-2.8.0/django_rq/management/commands/rqstats.py 2023-05-02 05:18:13.000000000 +0200 +++ new/django-rq-2.8.1/django_rq/management/commands/rqstats.py 2023-05-14 03:31:42.000000000 +0200 @@ -53,8 +53,8 @@ # Header click.echo( - """| %-15s|%10s |%10s |%10s |%10s |%10s |""" % - ("Name", "Queued", "Active", "Deferred", "Finished", "Workers") + """| %-15s|%10s |%10s |%10s |%10s |%10s |%10s |""" % + ("Name", "Queued", "Active", "Deferred", "Finished", "Failed", "Workers") ) self._print_separator() @@ -62,10 +62,11 @@ # Print every queues in a row for queue in statistics["queues"]: click.echo( - """| %-15s|%10s |%10s |%10s |%10s |%10s |""" % + """| %-15s|%10s |%10s |%10s |%10s |%10s |%10s |""" % (queue["name"], queue["jobs"], queue["started_jobs"], queue["deferred_jobs"], - queue["finished_jobs"], queue["workers"]) + queue["finished_jobs"],queue["failed_jobs"], + queue["workers"]) ) self._print_separator() @@ -95,7 +96,7 @@ self.interval = options.get("interval") # Arbitrary - self.table_width = 78 + self.table_width = 90 # Do not continuously poll if not self.interval: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-rq-2.8.0/django_rq/templates/django_rq/job_detail.html new/django-rq-2.8.1/django_rq/templates/django_rq/job_detail.html --- old/django-rq-2.8.0/django_rq/templates/django_rq/job_detail.html 2023-05-02 05:18:13.000000000 +0200 +++ new/django-rq-2.8.1/django_rq/templates/django_rq/job_detail.html 2023-05-14 03:31:42.000000000 +0200 @@ -186,6 +186,12 @@ <div class="submit-row"> <p class="deletelink-box"><a href="delete/" class="deletelink">Delete</a></p> + {% if job.is_started %} + <form method = 'POST' action = "{% url 'rq_stop_job' queue_index job.id %}"> + {% csrf_token %} + <input type="submit" value="Stop" class="deletelink" name="stop"> + </form> + {% endif %} {% if job.is_failed %} <form method = 'POST' action = "{% url 'rq_requeue_job' queue_index job.id %}"> {% csrf_token %} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-rq-2.8.0/django_rq/templates/django_rq/jobs.html new/django-rq-2.8.1/django_rq/templates/django_rq/jobs.html --- old/django-rq-2.8.0/django_rq/templates/django_rq/jobs.html 2023-05-02 05:18:13.000000000 +0200 +++ new/django-rq-2.8.1/django_rq/templates/django_rq/jobs.html 2023-05-14 03:31:42.000000000 +0200 @@ -54,6 +54,9 @@ {% if job_status == 'Failed' %} <option value="requeue">Requeue</option> {% endif %} + {% if job_status == 'Started' %} + <option value="stop">Stop</option> + {% endif %} </select> </label> <button type="submit" class="button" title="Execute selected action" name="index" value="0">Go</button> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-rq-2.8.0/django_rq/templates/django_rq/stats.html new/django-rq-2.8.1/django_rq/templates/django_rq/stats.html --- old/django-rq-2.8.0/django_rq/templates/django_rq/stats.html 2023-05-02 05:18:13.000000000 +0200 +++ new/django-rq-2.8.1/django_rq/templates/django_rq/stats.html 2023-05-14 03:31:42.000000000 +0200 @@ -7,7 +7,7 @@ <style>table {width: 100%;}</style> {% endblock %} -{% block content_title %}<h1>RQ Queues</h1>{% endblock %} +{% block content_title %}<h1>Queues</h1>{% endblock %} {% block breadcrumbs %} <div class="breadcrumbs"> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-rq-2.8.0/django_rq/tests/test_views.py new/django-rq-2.8.1/django_rq/tests/test_views.py --- old/django-rq-2.8.0/django_rq/tests/test_views.py 2023-05-02 05:18:13.000000000 +0200 +++ new/django-rq-2.8.1/django_rq/tests/test_views.py 2023-05-14 03:31:42.000000000 +0200 @@ -2,6 +2,7 @@ from datetime import datetime from unittest.mock import PropertyMock, patch + from django.contrib.auth.models import User from django.test import TestCase, override_settings from django.test.client import Client @@ -362,3 +363,35 @@ self.assertEqual(response.status_code, 200) self.assertNotIn("name", response.content.decode('utf-8')) self.assertIn('"error": true', response.content.decode('utf-8')) + + def test_action_stop_jobs(self): + queue = get_queue('django_rq_test') + queue_index = get_queue_index('django_rq_test') + + # Enqueue some jobs + job_ids, jobs = [], [] + worker = get_worker('django_rq_test') + for _ in range(3): + job = queue.enqueue(access_self) + job_ids.append(job.id) + jobs.append(job) + worker.prepare_job_execution(job) + + # Check if the jobs are started + for job_id in job_ids: + job = Job.fetch(job_id, connection=queue.connection) + self.assertEqual(job.get_status(), JobStatus.STARTED) + + # Stop those jobs using the view + started_job_registry = StartedJobRegistry(queue.name, connection=queue.connection) + self.assertEqual(len(started_job_registry), len(job_ids)) + self.client.post(reverse('rq_actions', args=[queue_index]), {'action': 'stop', 'job_ids': job_ids}) + for job in jobs: + worker.monitor_work_horse(job, queue) # Sets the job as Failed and removes from Started + self.assertEqual(len(started_job_registry), 0) + + canceled_job_registry = FailedJobRegistry(queue.name, connection=queue.connection) + self.assertEqual(len(canceled_job_registry), len(job_ids)) + + for job_id in job_ids: + self.assertIn(job_id, canceled_job_registry) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-rq-2.8.0/django_rq/urls.py new/django-rq-2.8.1/django_rq/urls.py --- old/django-rq-2.8.0/django_rq/urls.py 2023-05-02 05:18:13.000000000 +0200 +++ new/django-rq-2.8.1/django_rq/urls.py 2023-05-14 03:31:42.000000000 +0200 @@ -29,4 +29,7 @@ re_path( r'^queues/(?P<queue_index>[\d]+)/(?P<job_id>[^/]+)/enqueue/$', views.enqueue_job, name='rq_enqueue_job' ), + re_path( + r'^queues/(?P<queue_index>[\d]+)/(?P<job_id>[^/]+)/stop/$', views.stop_job, name='rq_stop_job' + ), ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-rq-2.8.0/django_rq/utils.py new/django-rq-2.8.1/django_rq/utils.py --- old/django-rq-2.8.0/django_rq/utils.py 2023-05-02 05:18:13.000000000 +0200 +++ new/django-rq-2.8.1/django_rq/utils.py 2023-05-14 03:31:42.000000000 +0200 @@ -7,6 +7,7 @@ StartedJobRegistry, clean_registries, ) +from rq.command import send_stop_job_command from rq.worker import Worker from rq.worker_registration import clean_worker_registry @@ -106,3 +107,16 @@ valid_jobs.append(job) return valid_jobs + +def stop_jobs(queue, job_ids): + job_ids = job_ids if isinstance(job_ids, (list, tuple)) else [job_ids] + stopped_job_ids = [] + failed_to_stop_job_ids = [] + for job_id in job_ids: + try: + send_stop_job_command(queue.connection, job_id) + except Exception: + failed_to_stop_job_ids.append(job_id) + continue + stopped_job_ids.append(job_id) + return stopped_job_ids, failed_to_stop_job_ids \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-rq-2.8.0/django_rq/views.py new/django-rq-2.8.1/django_rq/views.py --- old/django-rq-2.8.0/django_rq/views.py 2023-05-02 05:18:13.000000000 +0200 +++ new/django-rq-2.8.1/django_rq/views.py 2023-05-14 03:31:42.000000000 +0200 @@ -8,6 +8,7 @@ from django.shortcuts import redirect, render from django.urls import reverse from django.views.decorators.cache import never_cache +from django.views.decorators.http import require_POST from redis.exceptions import ResponseError from rq import requeue_job @@ -22,10 +23,11 @@ ) from rq.worker import Worker from rq.worker_registration import clean_worker_registry +from rq.command import send_stop_job_command from .queues import get_queue_by_index from .settings import API_TOKEN -from .utils import get_statistics, get_jobs +from .utils import get_statistics, get_jobs, stop_jobs @never_cache @@ -493,6 +495,12 @@ for job_id in job_ids: requeue_job(job_id, connection=queue.connection) messages.info(request, 'You have successfully requeued %d jobs!' % len(job_ids)) + elif request.POST['action'] == 'stop': + stopped, failed_to_stop = stop_jobs(queue, job_ids) + if len(stopped) >0 : + messages.info(request, 'You have successfully stopped %d jobs!' % len(stopped)) + if len(failed_to_stop) >0 : + messages.error(request, '%d jobs failed to stop!' % len(failed_to_stop)) return redirect(next_url) @@ -534,3 +542,19 @@ 'queue': queue, } return render(request, 'django_rq/delete_job.html', context_data) + + +@never_cache +@staff_member_required +@require_POST +def stop_job(request, queue_index, job_id): + """Stop started job""" + queue_index = int(queue_index) + queue = get_queue_by_index(queue_index) + stopped, _ = stop_jobs(queue, job_id) + if len(stopped) == 1: + messages.info(request, 'You have successfully stopped %s' % job_id) + return redirect('rq_job_detail', queue_index, job_id) + else: + messages.error(request, 'Failed to stop %s' % job_id) + return redirect('rq_job_detail', queue_index, job_id) \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-rq-2.8.0/integration_test/requirements.txt new/django-rq-2.8.1/integration_test/requirements.txt --- old/django-rq-2.8.0/integration_test/requirements.txt 2023-05-02 05:18:13.000000000 +0200 +++ new/django-rq-2.8.1/integration_test/requirements.txt 2023-05-14 03:31:42.000000000 +0200 @@ -1,5 +1,5 @@ -e .. -Django==3.2.18 +Django==3.2.19 gunicorn==20.1.0 psycopg2==2.9.6 -requests==2.29.0 +requests==2.30.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-rq-2.8.0/setup.py new/django-rq-2.8.1/setup.py --- old/django-rq-2.8.0/setup.py 2023-05-02 05:18:13.000000000 +0200 +++ new/django-rq-2.8.1/setup.py 2023-05-14 03:31:42.000000000 +0200 @@ -3,7 +3,7 @@ setup( name='django-rq', - version='2.8.0', + version='2.8.1', author='Selwin Ong', author_email='selwin....@gmail.com', packages=['django_rq'], @@ -14,7 +14,7 @@ zip_safe=False, include_package_data=True, package_data={'': ['README.rst']}, - install_requires=['django>=2.0', 'rq>=1.2', 'redis>=3'], + install_requires=['django>=2.0', 'rq>=1.14', 'redis>=3'], extras_require={ 'Sentry': ['raven>=6.1.0'], 'testing': ['mock>=2.0.0'],