Skip to content

Commit

Permalink
Merge pull request #24 from vintasoftware/feat/django-v5
Browse files Browse the repository at this point in the history
Add support for Django 4.2 and 5.0, and drop support for prior versions
  • Loading branch information
fjsj authored May 20, 2024
2 parents 64b4ebf + e8fa44d commit 7a7a649
Show file tree
Hide file tree
Showing 22 changed files with 373 additions and 234 deletions.
23 changes: 23 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# https://editorconfig.org

root = true

[*]
indent_style = space
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf

[*.{json,html,md,yml,yaml}]
indent_size = 2

[*.md]
trim_trailing_whitespace = false

[*.ini]
indent_style = tab

[Makefile]
indent_style = tab
30 changes: 30 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: tests

on: [push, pull_request]

jobs:
test:
name: Test (Python ${{ matrix.python-version }}, Django ${{ matrix.django-version }})

runs-on: ubuntu-latest

strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
django-version: ["4.2", "5.0"]

steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements_test.txt
- name: Run tests with coverage
run: tox -- --keepdb --parallel
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*.db
*~


/site/
/htmlcov/
/coverage/
Expand All @@ -17,5 +18,7 @@ coverage.*
.python-version
celerybeat-schedule
celerybeat-schedule.*
*.sqlite
*.sqlite3

!.gitignore
22 changes: 0 additions & 22 deletions .travis.yml

This file was deleted.

48 changes: 41 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
# Django Celery Beat Status

![PyPI - Version](https://img.shields.io/pypi/v/django-celerybeat-status)
![Supported Python Versions](https://img.shields.io/pypi/pyversions/django-celerybeat-status.svg)
[![Build Status](https://github.com/vintasoftware/django-celerybeat-status/actions/workflows/tests.yml/badge.svg)](https://github.com/vintasoftware/django-celerybeat-status/actions/workflows/tests.yml)
[![Coverage Status](https://coveralls.io/repos/github/vintasoftware/django-celerybeat-status/badge.svg?branch=main)](https://coveralls.io/github/vintasoftware/django-celerybeat-status?branch=main)

A library that integrates with django admin and shows in a simple GUI when your periodic are going to run next.

## Instalation

``` bash
```bash
pip install django-celerybeat-status
```

## Configuration

1. Add `'celerybeat_status'` to your `INSTALLED_APPS` variable in django settings
1. Add `"celerybeat_status"` to your `INSTALLED_APPS` variable in django settings

``` python
```python
INSTALLED_APPS = [
...
'celerybeat_status',
"celerybeat_status",
]
```

2. Create a url for the status check view

```python
from django.conf.urls import url, include
from django.urls import include, path

urlpatterns = [
# other urls...
url(r'^admin/statuscheck/', include('celerybeat_status.urls', namespce='celerybeat_status')),
path("admin/statuscheck/", include("celerybeat_status.urls", namespace="celerybeat_status")),
]
```

Expand All @@ -40,11 +45,40 @@ How you admin page will look like:

![admin-page](https://raw.githubusercontent.com/vintasoftware/django-celerybeat-status/master/README_IMAGES/django-celerybeat-status-admin.png)


How your tasks will be shown:

![tasks-page](https://raw.githubusercontent.com/vintasoftware/django-celerybeat-status/master/README_IMAGES/django-celerybeat-status-tasks.png)

## Contributing

### Setting up the development environment

1. Clone the repository.

2. Create a virtual environment.

3. Install the dependencies.

```bash
pip install -r requirements_test.txt
```

4. Run the project. Relevant to check UI changes.

```bash
# Create the database and run the migrations.
python manage.py migrate
# Create a superuser. This will allow you to access the admin interface.
python manage.py createsuperuser
# Start the development server. You can view the application by navigating to the URL provided in the terminal.
python manage.py runserver
```

5. Run the tests. This package uses `tox` to run tests on multiple evironments, please make sure they are passing before submitting a pull request.

```bash
tox
```

## Commercial Support

Expand Down
10 changes: 5 additions & 5 deletions celerybeat_status/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# -*- coding: utf-8
__title__ = 'CeleryBeat Status'
__version__ = '0.0.10'
__author__ = 'Vinta Software'
__license__ = 'MIT License'
__copyright__ = 'Copyright 2017 Vinta Serviços e Soluções Tecnológicas Ltda'
__title__ = "CeleryBeat Status"
__version__ = "1.0.0"
__author__ = "Vinta Software"
__license__ = "MIT License"
__copyright__ = "Copyright 2017 Vinta Serviços e Soluções Tecnológicas Ltda"

# Version synonym
VERSION = __version__
3 changes: 2 additions & 1 deletion celerybeat_status/admin.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from django.contrib.admin.sites import AdminSite
AdminSite.index_template = 'celerybeat_status/custom_admin/index.html'

AdminSite.index_template = "celerybeat_status/custom_admin/index.html"
2 changes: 1 addition & 1 deletion celerybeat_status/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@


class CeleryBeatStatusConfig(AppConfig):
name = 'celerybeat_status'
name = "celerybeat_status"
24 changes: 14 additions & 10 deletions celerybeat_status/helpers.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from celery.beat import Service
from django.utils import timezone
import datetime
import json

from celery.beat import Service
from django.utils import timezone


def get_periodic_tasks_info():
from celery import current_app

schedule = Service(current_app).get_scheduler().get_schedule()
tasks = []
for key, entry in schedule.items():
Expand All @@ -17,13 +19,15 @@ def get_periodic_tasks_info():
# remove delay between the timezone.now and the schedule entry due date
next_execution = next_execution.replace(microsecond=0)

tasks.append({
'name': key,
'task': entry.task,
'args': '(' + ', '.join([json.dumps(arg) for arg in entry.args]) + ')',
'kwargs': json.dumps(entry.kwargs),
'is_due': is_due_tpl[0],
'next_execution': next_execution
})
tasks.append(
{
"name": key,
"task": entry.task,
"args": "(" + ", ".join([json.dumps(arg) for arg in entry.args]) + ")",
"kwargs": json.dumps(entry.kwargs),
"is_due": is_due_tpl[0],
"next_execution": next_execution,
}
)

return tasks
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
{% load i18n static %}

{% block sidebar %}
{% include "admin/sidebar.html" %}
{% include "celerybeat_status/custom_admin/sidebar.html" %}
{% endblock %}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div id="content-related">
{% include "admin/sidebar_widgets/statuscheck.html" %}
{% include "admin/sidebar_widgets/actions.html" %}
{% include "celerybeat_status/custom_admin/sidebar_widgets/statuscheck.html" %}
{% include "celerybeat_status/custom_admin/sidebar_widgets/actions.html" %}
</div>
37 changes: 26 additions & 11 deletions celerybeat_status/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
from django.utils import version as django_version
from django.contrib.auth import get_user_model
from django.urls import reverse

from celerybeat_status.tests.utils import (
SuperuserBaseTestCase, TestRequiresSuperuser)
from celerybeat_status.tests.utils import BaseTestCase, TestRequiresAuthenticatedUser

if django_version.get_complete_version() < (2, 0, 0):
from django.core.urlresolvers import reverse
else:
from django.urls import reverse
User = get_user_model()


class PeriodicTaskStatusListTests(
TestRequiresSuperuser, SuperuserBaseTestCase):
view_name = 'periodic-tasks-status'
class PeriodicTasksStatusListViewTests(TestRequiresAuthenticatedUser, BaseTestCase):
view_name = "celerybeat_status:periodic-tasks-status"

def setUp(self):
super(PeriodicTaskStatusListTests, self).setUp()
super().setUp()
self.view_url = reverse(self.view_name)

def test_non_authenticated_user_is_redirected(self):
response = self.client.get(self.view_url)
self.assertRedirects(response, "/admin/login/?next=" + self.view_url)

def test_regular_user_access_returns_forbidden(self):
self.client.force_login(self.regular_user)
response = self.client.get(self.view_url)
self.assertEqual(response.status_code, 403)

def test_staff_user_access_returns_forbidden(self):
self.client.force_login(self.staff_user)
response = self.client.get(self.view_url)
self.assertEqual(response.status_code, 403)

def test_superuser_access_returns_success(self):
self.client.force_login(self.superuser)
response = self.client.get(self.view_url)
self.assertEqual(response.status_code, 200)
60 changes: 23 additions & 37 deletions celerybeat_status/tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,38 @@
from django.test import TestCase, Client
from django.contrib.auth import get_user_model
from django.test import Client, TestCase

User = get_user_model()


class BaseTestCase(TestCase):

def setUp(self):
super(BaseTestCase, self).setUp()
self.user_email = '[email protected]'
self.user_password = 'the_password'
self.user = User.objects.create_user(
username='testuser', email=self.user_email,
password=self.user_password)

self.auth_client = Client()
self.auth_client.force_login(self.user)


class SuperuserBaseTestCase(BaseTestCase):

def setUp(self):
self.superuser_email = '[email protected]'
self.superuser_password = 'the_password'
self.superuser = User.objects.create_superuser(
username='testsuperuser',
email=self.superuser_email,
password=self.superuser_password)

self.super_client = Client()
self.super_client.force_login(self.superuser)

super(SuperuserBaseTestCase, self).setUp()
super().setUp()
self.regular_user = User.objects.create_user(
username="regular",
email="[email protected]",
password="123",
is_staff=False,
is_superuser=False,
)
self.staff_user = User.objects.create_user(
username="staff",
email="[email protected]",
password="123",
is_staff=True,
is_superuser=False,
)
self.superuser = User.objects.create_user(
username="super",
email="[email protected]",
password="123",
is_staff=True,
is_superuser=True,
)


class TestRequiresAuthenticatedUser(object):

def test_requires_authenticated_user(self):
response = self.client.get(self.view_url)
self.assertEqual(response.status_code, 302)


class TestRequiresSuperuser(TestRequiresAuthenticatedUser):

def test_requires_superuser(self):
response = self.auth_client.get(self.view_url)
self.assertEqual(response.status_code, 302)

def test_superuser_get_request_success(self):
response = self.super_client.get(self.view_url)
self.assertEqual(response.status_code, 200)
10 changes: 7 additions & 3 deletions celerybeat_status/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from django.conf.urls import url
from django.urls import path

from celerybeat_status.views import PeriodicTasksStatusListView

app_name = "celerybeat_status"

urlpatterns = [
url(r'^periodic-tasks/$', PeriodicTasksStatusListView.as_view(),
name='periodic-tasks-status'),
path(
"periodic-tasks/",
PeriodicTasksStatusListView.as_view(),
name="periodic-tasks-status",
),
]
Loading

0 comments on commit 7a7a649

Please sign in to comment.