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'],

Reply via email to