couldn't stay away, implemented all the basics for domains, mailboxes and aliases

This commit is contained in:
j3d1 2020-11-06 00:56:22 +01:00
parent 1d01e66a4d
commit 66eb84bb8e
15 changed files with 328 additions and 87 deletions

View file

@ -17,6 +17,6 @@ from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('multimail/', include('multimail.urls')),
path('', include('multimail.urls')),
path('admin/', admin.site.urls),
]

View file

@ -1,29 +1,32 @@
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.views import generic
from django.utils import timezone
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth import logout as auth_logout
from .models import Choice, Question, Domain
from .models import Domain, Mailbox, Alias
@login_required(login_url='/login/')
def delete_domain(request, domain_id):
domain = get_object_or_404(Domain, pk=domain_id)
domain.delete()
return HttpResponseRedirect(reverse('multimail:domains'))
@login_required(login_url='/login/')
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'multimail/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('multimail:results', args=(question.id,)))
def delete_mailbox(request, mailbox_id):
mailbox = get_object_or_404(Mailbox, pk=mailbox_id)
mailbox.delete()
return HttpResponseRedirect(reverse('multimail:mailboxes'))
@login_required(login_url='/login/')
def delete_alias(request, alias_id):
alias = get_object_or_404(Alias, pk=alias_id)
alias.delete()
return HttpResponseRedirect(reverse('multimail:aliases'))
def logout(request):
auth_logout(request)
return HttpResponseRedirect(reverse('multimail:login'))

View file

@ -0,0 +1,64 @@
from django.contrib.auth.decorators import login_required
from django.forms import ModelForm
from django.http import HttpResponseRedirect
from django.shortcuts import render
from multimail.models import Domain, Mailbox, Alias
class DomainForm(ModelForm):
class Meta:
model = Domain
fields = ['domain']
class MailboxForm(ModelForm):
class Meta:
model = Mailbox
fields = '__all__'
class AliasForm(ModelForm):
class Meta:
model = Alias
fields = '__all__'
@login_required(login_url='/login/')
def edit_domain(request, domain_id):
domain = Domain.objects.get(id=domain_id)
if request.method == 'POST':
form = DomainForm(request.POST, instance=domain)
if form.is_valid():
form.save()
return HttpResponseRedirect('/domains/')
else:
form = DomainForm(instance=domain)
return render(request, 'multimail/edit_domain.html', {'form': form})
@login_required(login_url='/login/')
def edit_mailbox(request, mailbox_id):
mailbox = Mailbox.objects.get(id=mailbox_id)
if request.method == 'POST':
form = MailboxForm(request.POST, instance=mailbox)
if form.is_valid():
form.save()
return HttpResponseRedirect('/mailboxes/')
else:
form = MailboxForm(instance=mailbox)
return render(request, 'multimail/edit_mailbox.html', {'form': form})
@login_required(login_url='/login/')
def edit_alias(request, alias_id):
alias = Alias.objects.get(id=alias_id)
if request.method == 'POST':
form = AliasForm(request.POST, instance=alias)
if form.is_valid():
form.save()
return HttpResponseRedirect('/aliases/')
else:
form = AliasForm(instance=alias)
return render(request, 'multimail/edit_alias.html', {'form': form})

View file

@ -0,0 +1,31 @@
{% extends 'multimail/base.html' %}
{% block content %}
<h1 class="mt-4">Aliases</h1>
{% if alias_list %}
<table class="table table-striped table-responsive-md btn-table">
<thead>
<tr>
<th scope="col">Source</th>
<th scope="col">Destination</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
{% for alias in alias_list %}
<tr>
<th scope="row"><a href="{% url 'multimail:edit_alias' alias.id %}">{{ alias.source_username }}@{{ alias.source_domain }}</a></th>
<th scope="row">{{ alias.destination_username }}@{{ alias.destination_domain }}</th>
<td><a href="{% url 'multimail:delete_alias' alias.id %}" class="btn btn-danger btn-sm m-0">Delete</a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>You haven't set up any aliases yet.</p>
{% endif %}
{% endblock %}

View file

@ -16,6 +16,7 @@
<!-- Custom styles for this template -->
<link href="{% static 'multimail/css/simple-sidebar.css' %}" rel="stylesheet">
<link href="{% static "fontawesome/css/all.min.css" %}" rel="stylesheet" type="text/css"/>
</head>
@ -29,7 +30,7 @@
<div class="list-group list-group-flush">
<a href="{% url 'multimail:domains' %}" class="list-group-item list-group-item-action bg-light">Domains</a>
<a href="{% url 'multimail:mailboxes' %}" class="list-group-item list-group-item-action bg-light">Mailboxes</a>
<a href="#" class="list-group-item list-group-item-action bg-light">Aliases</a>
<a href="{% url 'multimail:aliases' %}" class="list-group-item list-group-item-action bg-light">Aliases</a>
</div>
</div>
<!-- /#sidebar-wrapper -->

View file

@ -1,12 +0,0 @@
<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'multimail:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
<input type="submit" value="Vote">
</form>

View file

@ -4,13 +4,26 @@
<h1 class="mt-4">Domains</h1>
{% if domain_list %}
<ul>
{% for question in domain_list %}
<li><a href="{% url 'multimail:detail' question.id %}">{{ question.domain }}</a></li>
<table class="table table-striped table-responsive-md btn-table">
<thead>
<tr>
<th scope="col">Domain</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
{% for domain in domain_list %}
<tr>
<th scope="row"><a href="{% url 'multimail:edit_domain' domain.id %}">{{ domain.domain }}</a></th>
<td><a href="{% url 'multimail:delete_domain' domain.id %}" class="btn btn-danger btn-sm m-0">Delete</a></td>
</tr>
{% endfor %}
</ul>
</tbody>
</table>
{% else %}
<p>No multimail are available.</p>
<p>You haven't set up any domains yet.</p>
{% endif %}
{% endblock %}

View file

@ -0,0 +1,18 @@
{% extends 'multimail/base.html' %}
{% load bootstrap4 %}
{% block content %}
<h1 class="mt-4">{{ form.source_username.value }}@{{ form.source_domain.value }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">Submit</button>
{% endbuttons %}
</form>
{% endblock %}

View file

@ -0,0 +1,17 @@
{% extends 'multimail/base.html' %}
{% load bootstrap4 %}
{% block content %}
<h1 class="mt-4">{{ form.domain.value }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">Submit</button>
{% endbuttons %}
</form>
{% endblock %}

View file

@ -0,0 +1,17 @@
{% extends 'multimail/base.html' %}
{% load bootstrap4 %}
{% block content %}
<h1 class="mt-4">{{ form.username.value }}@{{ form.domain.value }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">Submit</button>
{% endbuttons %}
</form>
{% endblock %}

View file

@ -0,0 +1,83 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Multimail</title>
<!-- Bootstrap core CSS -->
<link href="{% static 'vendor/bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="{% static 'multimail/css/simple-sidebar.css' %}" rel="stylesheet">
<link href="{% static "fontawesome/css/all.min.css" %}" rel="stylesheet" type="text/css"/>
</head>
<body>
<div class="container" style="height:100vh;">
<div class="row h-100 justify-content-center align-items-center">
<div class="card col-6">
<article class="card-body">
<h4 class="card-title text-center mb-4 mt-1">Sign in</h4>
<hr>
{% if form.non_field_errors %}
<div class="alert alert-danger" role="alert">
<ul>
{% for error in form.non_field_errors %}
<li>{{ error|escape }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<form method="POST">{% csrf_token %}
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"> <i class="fa fa-user"></i> </span>
</div>
<input id="{{ form.username.id_for_label }}" name="{{ form.username.html_name }}"
class="form-control" placeholder="Email or login" type="text" requird>
</div> <!-- input-group.//-->
{% if form.username.errors %}
<p class="text-danger text-center">
{% for error in form.username.errors %}
{{ error|escape }}<br>
{% endfor %}
</p>
{% endif %}
</div> <!-- form-group// -->
<div class="form-group">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"> <i class="fa fa-lock"></i> </span>
</div>
<input id="{{ form.password.id_for_label }}" name="{{ form.password.html_name }}"
class="form-control" placeholder="******" type="password" required>
</div> <!-- input-group.// -->
{% if form.password.errors %}
<p class="text-danger text-center">
{% for error in form.password.errors %}
{{ error|escape }}<br>
{% endfor %}
</p>
{% endif %}
</div> <!-- form-group// -->
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block"> Login</button>
</div> <!-- form-group// -->
<!--p class="text-center"><a href="#" class="btn">Forgot password?</a></p-->
</form>
</article>
</div>
</div>
</div>
</body>
</html>

View file

@ -4,13 +4,26 @@
<h1 class="mt-4">Mailboxes</h1>
{% if mailbox_list %}
<ul>
{% for question in mailbox_list %}
<li><a href="{% url 'multimail:detail' question.id %}">{{ question.domain }}</a></li>
<table class="table table-striped table-responsive-md btn-table">
<thead>
<tr>
<th scope="col">Mailbox</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
{% for mailbox in mailbox_list %}
<tr>
<th scope="row"><a href="{% url 'multimail:edit_mailbox' mailbox.id %}">{{ mailbox.username }}@{{ mailbox.domain }}</a></th>
<td><a href="{% url 'multimail:delete_mailbox' mailbox.id %}" class="btn btn-danger btn-sm m-0">Delete</a></td>
</tr>
{% endfor %}
</ul>
</tbody>
</table>
{% else %}
<p>No multimail are available.</p>
<p>You haven't set up any mailboxes yet.</p>
{% endif %}
{% endblock %}

View file

@ -1,9 +0,0 @@
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>
<a href="{% url 'multimail:detail' question.id %}">Vote again?</a>

View file

@ -1,17 +1,25 @@
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
from . import views, forms
from . import actions
app_name = 'multimail'
urlpatterns = [
path('', views.DomainListView.as_view(), name='index'),
path('domains/', views.DomainListView.as_view(), name='domains'),
path('domain/<int:domain_id>/', forms.edit_domain, name='edit_domain'),
path('domain/<int:domain_id>/delete', actions.delete_domain, name='delete_domain'),
path('mailboxes/', views.MailboxListView.as_view(), name='mailboxes'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
path('<int:question_id>/vote/', actions.vote, name='vote'),
path('login/', auth_views.LoginView.as_view(), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
path('mailbox/<int:mailbox_id>/', forms.edit_mailbox, name='edit_mailbox'),
path('mailbox/<int:mailbox_id>/delete', actions.delete_mailbox, name='delete_mailbox'),
path('aliases/', views.AliasListView.as_view(), name='aliases'),
path('alias/<int:alias_id>/', forms.edit_alias, name='edit_alias'),
path('alias/<int:alias_id>/delete', actions.delete_alias, name='delete_alias'),
path('login/', views.UserLoginView.as_view(), name='login'),
path('logout/', actions.logout, name='logout'),
]

View file

@ -1,17 +1,16 @@
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
from django.utils import timezone
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.views import LoginView
from .models import Choice, Question, Domain, Mailbox
from .models import Domain, Mailbox, Alias
class UserLoginView(LoginView):
template_name = 'multimail/login.html'
class DomainListView(LoginRequiredMixin, generic.ListView):
login_url = 'login/'
# redirect_field_name = 'redirect_to'
template_name = 'multimail/domains.html'
context_object_name = 'domain_list'
@ -23,9 +22,9 @@ class DomainListView(LoginRequiredMixin, generic.ListView):
# ).order_by('-pub_date')[:5]
return Domain.objects.all()
class MailboxListView(LoginRequiredMixin, generic.ListView):
login_url = 'login/'
# redirect_field_name = 'redirect_to'
template_name = 'multimail/mailboxes.html'
context_object_name = 'mailbox_list'
@ -38,20 +37,15 @@ class MailboxListView(LoginRequiredMixin, generic.ListView):
return Mailbox.objects.all()
class DetailView(LoginRequiredMixin, generic.DetailView):
class AliasListView(LoginRequiredMixin, generic.ListView):
login_url = 'login/'
model = Question
template_name = 'multimail/detail.html'
template_name = 'multimail/aliases.html'
context_object_name = 'alias_list'
def get_queryset(self):
"""
Excludes any questions that aren't published yet.
"""
return Question.objects.filter(pub_date__lte=timezone.now())
class ResultsView(LoginRequiredMixin, generic.DetailView):
login_url = 'login/'
model = Question
template_name = 'multimail/results.html'
print(self.request.user)
"""Return the last five published questions."""
# return Domain.objects.filter(
# pub_date__lte=timezone.now()
# ).order_by('-pub_date')[:5]
return Alias.objects.all()