Compare commits

..

No commits in common. "master" and "0.8.8" have entirely different histories.

18 changed files with 33 additions and 266 deletions

1
.gitignore vendored
View File

@ -3,4 +3,3 @@
/django_gas.egg-info
/.coverage
/htmlcov
*.pyc

View File

@ -1,31 +1,6 @@
Changelog
=========
0.8.13
------
* Fix: set html email template
0.8.12
------
* Add reset password (thanks Leo!)
0.8.11
------
* Add preview widget in Image Field Form (thanks Leo!)
0.8.10
-----
* New templatetag to check if user has role
0.8.9
-----
* Bugfix
0.8.8
-----

View File

@ -2,4 +2,3 @@ Collaborators
=============
* Shakarina
* Leo Hakim

View File

@ -8,9 +8,5 @@ urlpatterns = [
path('login/', views.GASLoginView.as_view(), name='login'),
path('logout/', logout_then_login, {'login_url': 'gas:login'}, name='logout'),
path('change-password/', views.GASPasswordChangeView.as_view(), name='change_password'),
path('reset-password-confirm/<uidb64>/<token>/', views.GASPasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('reset-password-confirm/done/', views.GASPasswordResetCompleteView.as_view(), name='password_reset_complete'),
path('reset-password/done/', views.GASPasswordResetDoneView.as_view(), name='password_reset_done'),
path('reset-password/', views.GASPasswordResetView.as_view(), name='reset_password'),
path('', views.Index.as_view(), name='index'),
]

View File

@ -1,72 +1,45 @@
from django.contrib.auth.views import (
LoginView,
PasswordChangeView,
PasswordResetConfirmView,
PasswordResetDoneView,
PasswordResetView,
)
from django.contrib.auth.views import LoginView, PasswordChangeView
from django.shortcuts import resolve_url
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from django.views.generic import TemplateView
from gas import gas_settings
from gas.views import GASMixin
class GASPasswordChangeView(GASMixin, PasswordChangeView):
template_name = "gas/base_form.html"
success_url = reverse_lazy("gas:index")
continue_url = reverse_lazy("gas:change_password")
title = _("Change your password")
success_message = _("Password changed.")
from gas import gas_settings
class Index(GASMixin, TemplateView):
main_menu = "index"
template_name = "gas/index.html"
roles = ("staff",)
class GASContextMixin:
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
css = gas_settings.MEDIA["css"]
javascript = gas_settings.MEDIA["js"]
if gas_settings.EXTRA_MEDIA:
css = css + gas_settings.EXTRA_MEDIA.get("css", [])
javascript = javascript + gas_settings.EXTRA_MEDIA.get("js", [])
ctx.update(
{
"logo_static_url": gas_settings.LOGO,
"css": css,
"js": javascript,
}
)
return ctx
class GASLoginView(GASContextMixin, LoginView):
class GASLoginView(LoginView):
template_name = "gas/login.html"
def get_success_url(self):
url = self.get_redirect_url()
return url or resolve_url("gas:index")
return url or resolve_url('gas:index')
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
css = gas_settings.MEDIA['css']
javascript = gas_settings.MEDIA['js']
if gas_settings.EXTRA_MEDIA:
css = css + gas_settings.EXTRA_MEDIA.get('css', [])
javascript = javascript + gas_settings.EXTRA_MEDIA.get('js', [])
ctx.update({
'logo_static_url': gas_settings.LOGO,
'css': css,
'js': javascript,
})
return ctx
class GASPasswordResetView(GASContextMixin, PasswordResetView):
template_name = "gas/reset.html"
html_email_template_name = "registration/password_reset_email.html"
success_url = reverse_lazy("gas:password_reset_done")
class GASPasswordChangeView(GASMixin, PasswordChangeView):
template_name = 'gas/base_form.html'
success_url = reverse_lazy('gas:index')
continue_url = reverse_lazy('gas:change_password')
title = _('Change your password')
success_message = _('Password changed.')
class GASPasswordResetDoneView(GASContextMixin, PasswordResetDoneView):
template_name = "gas/reset_done.html"
class GASPasswordResetConfirmView(GASContextMixin, PasswordResetConfirmView):
template_name = "gas/reset_confirm.html"
success_url = reverse_lazy("gas:password_reset_complete")
class GASPasswordResetCompleteView(GASContextMixin, TemplateView):
template_name = "gas/reset_complete.html"
class Index(GASMixin, TemplateView):
main_menu = 'index'
template_name = "gas/index.html"
roles = ('staff',)

View File

@ -20,5 +20,3 @@ MEDIA = getattr(settings, 'GAS_MEDIA', {
})
EXTRA_MEDIA = getattr(settings, 'GAS_EXTRA_MEDIA', None)
IMAGE_PREVIEW_WIDTH = getattr(settings, 'IMAGE_PREVIEW_WIDTH', 240)

View File

@ -86,7 +86,7 @@ class GASSite:
for prefix, urls in self._registry['urls'].items():
if prefix:
urlpatterns.append(
re_path(f'^{prefix}/', include(urls)),
re_path(r'^{prefix}/', include(urls)),
)
else:
urlpatterns.append(

View File

@ -262,7 +262,3 @@ label {
width: 20em;
padding: 1em;
}
.preview {
display: block;
}

View File

@ -1,14 +0,0 @@
{% load i18n %}{% autoescape off %}
{% blocktranslate %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktranslate %}
{% translate "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'gas:password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
{% translate 'Your username, in case youve forgotten:' %} {{ user.get_username }}
{% translate "Thanks for using our site!" %}
{% blocktranslate %}The {{ site_name }} team{% endblocktranslate %}
{% endautoescape %}

View File

@ -1,20 +0,0 @@
{% load i18n static form_tags %}<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>{{ gas_title }} {% trans "Login" %}</title>
{% for cssfile in css %}
<link href="{% static cssfile %}" rel="stylesheet" type="text/css" />
{% endfor %}
</head>
<body id="login">
<p>{% translate 'Forgotten your password? Enter your email address below, and well email instructions for setting a new one.' %}</p>
<form action="." method="POST">{% csrf_token %}
{% form_errors form %}
{% form_field form.email %}
<input type="hidden" name="next" value="{{ next }}">
<button type="submit">{% trans "Reset my password" %}</button>
</form>
</body>
</html>

View File

@ -1,14 +0,0 @@
{% load i18n static form_tags %}<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>{{ gas_title }} {% trans "Login" %}</title>
{% for cssfile in css %}
<link href="{% static cssfile %}" rel="stylesheet" type="text/css" />
{% endfor %}
</head>
<body id="login">
<p>{% translate 'Your password was changed.' %}</p>
</body>
</html>

View File

@ -1,26 +0,0 @@
{% load i18n static form_tags %}<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>{{ gas_title }} {% trans "Login" %}</title>
{% for cssfile in css %}
<link href="{% static cssfile %}" rel="stylesheet" type="text/css" />
{% endfor %}
</head>
<body id="login">
{% if validlink %}
<p>{% translate "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
<form action="." method="POST">{% csrf_token %}
<input class="hidden" autocomplete="username" value="{{ form.user.get_username }}">
{% form_errors form %}
{% form_field form.new_password1 %}
{% form_field form.new_password2 %}
<input type="hidden" name="next" value="{{ next }}">
<button type="submit">{% trans "Change my password" %}</button>
</form>
{% else %}
<p>{% translate "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}</p>
{% endif %}
</body>
</html>

View File

@ -1,17 +0,0 @@
{% load i18n static form_tags %}<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>{{ gas_title }} {% trans "Login" %}</title>
{% for cssfile in css %}
<link href="{% static cssfile %}" rel="stylesheet" type="text/css" />
{% endfor %}
</head>
<body id="login">
<p>{% translate 'Weve emailed you instructions for setting your password, if an account exists with the email you entered. You should receive them shortly.' %}</p>
<p>{% translate 'If you dont receive an email, please make sure youve entered the address you registered with, and check your spam folder.' %}</p>
</body>
</html>

View File

@ -1,5 +0,0 @@
{% if widget.is_initial %}{{ widget.initial_text }}: <a href="{{ widget.value.url }}"><img src="{{ widget.value.url }}" width="{{ widget.attrs.IMAGE_PREVIEW_WIDTH }}" class="preview" /></a>{% if not widget.required %}
<input type="checkbox" name="{{ widget.checkbox_name }}" id="{{ widget.checkbox_id }}"{% if widget.attrs.disabled %} disabled{% endif %}>
<label for="{{ widget.checkbox_id }}">{{ widget.clear_checkbox_label }}</label>{% endif %}<br>
{{ widget.input_text }}:{% endif %}
<input type="{{ widget.type }}" name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>

View File

@ -1,8 +1,7 @@
from django import forms, template
from django import forms
from django import template
from django.template.loader import render_to_string
from ..gas_settings import IMAGE_PREVIEW_WIDTH
register = template.Library()
@ -20,10 +19,6 @@ def base_form_field(field, css=None, container_class='', add_another_url=None, f
elif isinstance(field.field, forms.DateField):
field.field.widget.input_type = 'date'
if isinstance(field.field, forms.ImageField):
field.field.widget.template_name = 'gas/tags/widgets/image_preview.html'
field.field.widget.attrs['IMAGE_PREVIEW_WIDTH'] = IMAGE_PREVIEW_WIDTH
if isinstance(field.field, forms.SplitDateTimeField):
field.field.widget.widgets[1].attrs['placeholder'] = '00:00:00'
else:

View File

@ -5,7 +5,6 @@ from django import template
from django.utils.html import mark_safe
from ..sites import site
from ..models import UserRole
register = template.Library()
@ -60,10 +59,3 @@ def pagination(request, page):
@register.filter
def to_json(data):
return mark_safe(json.dumps(data))
@register.filter
def has_role(user, role):
if user.is_superuser:
return True
return UserRole.objects.filter(role__in=(role, "admins"), user=user).exists()

View File

@ -1,60 +0,0 @@
from django.test import TestCase, Client
from django.urls import reverse
from model_bakery import baker
class GASLoginTestCase(TestCase):
def test_load(self):
client = Client()
response = client.get(reverse("gas:login"))
self.assertEqual(response.status_code, 200)
class IndexTestCase(TestCase):
def test_load(self):
admin_user = baker.make(
"auth.User",
username="admin",
is_superuser=True,
)
client = Client()
response = client.get(reverse("gas:index"))
self.assertEqual(response.status_code, 302)
client.force_login(admin_user)
response = client.get(reverse("gas:index"))
self.assertEqual(response.status_code, 200)
class GASPasswordResetViewTestCase(TestCase):
def test_load(self):
client = Client()
response = client.get(reverse("gas:reset_password"))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "gas/reset.html")
class GASPasswordResetDoneViewTestCase(TestCase):
def test_load(self):
client = Client()
response = client.get(reverse("gas:password_reset_done"))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "gas/reset_done.html")
class GASPasswordResetConfirmViewTestCase(TestCase):
def test_load(self):
client = Client()
response = client.get(reverse("gas:password_reset_confirm", kwargs={"uidb64": "uidb64", "token": "token"}))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "gas/reset_confirm.html")
class GASPasswordResetCompleteViewTestCase(TestCase):
def test_load(self):
client = Client()
response = client.get(reverse("gas:password_reset_complete"))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "gas/reset_complete.html")

View File

@ -1,6 +1,6 @@
[metadata]
name = django-gas
version = 0.8.13
version = 0.8.8
description = An alternative to django admin
long_description = file: readme.md, changelog.md, collaborators.md
long_description_content_type = text/markdown