Initial import
@@ -0,0 +1,13 @@
|
||||
Copyright (c) 2009, Antoine Nguyen <tonio@ngyn.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
@@ -0,0 +1,29 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- Python version 2.5+
|
||||
- Django version 1.0+ (http://docs.djangoproject.com/en/dev/intro/install/#intro-install)
|
||||
|
||||
How to install
|
||||
--------------
|
||||
|
||||
Download Mailng's tarball and extract it::
|
||||
tar xzf mailng-<version>.tar.gz
|
||||
|
||||
Enter the mailng repository, create a settings.py file (you can use settings-sample.py as a model). Specify database relative informations. You must choose between mysql and postgresql, other types are not supported by major email projects like postfix or dovecot.
|
||||
|
||||
Initialise the database by running the following command::
|
||||
python manage.py syncdb
|
||||
|
||||
Create the super admin account (just follow the procedure).
|
||||
|
||||
Testing installation
|
||||
--------------------
|
||||
|
||||
As a typical Django application, Mailng can be tested using a simple web server. Just run this command to start it::
|
||||
python manage.py runserver
|
||||
|
||||
You will be able to play with mailng by looking at http://<youraddress>:8000/mailng/admin/
|
||||
@@ -0,0 +1,7 @@
|
||||
Mailng is a light web messaging solution. It provides different tools that facilitates virtual domains hosting. It is designed to be integrated with email servers like postfix (http://www.postfix.org/) and/or dovecot (http://www.dovecot.org/).
|
||||
|
||||
For now, only the administration component is available. Additional tools will come in a near future.
|
||||
|
||||
Django is needed to use Mailng (http://www.djangoproject.com/)
|
||||
|
||||
Mootools version 1.2 (http://www.mootools.net/) and SqueezeBox version 1.1 (http://digitarald.de/project/squeezebox/) are provided with Mailng.
|
||||
@@ -0,0 +1,34 @@
|
||||
from django import forms
|
||||
from mailng.admin.models import Domain, Mailbox, Alias
|
||||
|
||||
class DomainForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Domain
|
||||
|
||||
class MailboxForm(forms.ModelForm):
|
||||
password1 = forms.CharField(label="Password", widget=forms.PasswordInput)
|
||||
password2 = forms.CharField(label="Confirmation", widget=forms.PasswordInput)
|
||||
enabled = forms.BooleanField(label="Enabled", required=False)
|
||||
|
||||
class Meta:
|
||||
model = Mailbox
|
||||
fields = ('name', 'address', 'quota')
|
||||
|
||||
def clean_password2(self):
|
||||
if self.cleaned_data["password1"] != self.cleaned_data["password2"]:
|
||||
raise forms.ValidationError("Passwords mismatch")
|
||||
return self.cleaned_data["password2"]
|
||||
|
||||
class AliasForm(forms.ModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
domain = None
|
||||
if kwargs.has_key("domain"):
|
||||
domain = kwargs["domain"]
|
||||
del kwargs["domain"]
|
||||
super(AliasForm, self).__init__(*args, **kwargs)
|
||||
if domain:
|
||||
self.fields['mbox'].queryset = Mailbox.objects.filter(domain=domain.id)
|
||||
|
||||
class Meta:
|
||||
model = Alias
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
# Create your models here.
|
||||
|
||||
class Domain(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
quota = models.IntegerField()
|
||||
enabled = models.BooleanField()
|
||||
|
||||
class Mailbox(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
address = models.CharField(max_length=100)
|
||||
# password = models.CharField(max_length=100)
|
||||
quota = models.IntegerField()
|
||||
# enabled = models.BooleanField()
|
||||
uid = models.IntegerField()
|
||||
gid = models.IntegerField()
|
||||
path = models.CharField(max_length=200)
|
||||
domain = models.ForeignKey(Domain)
|
||||
user = models.ForeignKey(User)
|
||||
|
||||
def __str__(self):
|
||||
return "%s" % (self.address)
|
||||
|
||||
|
||||
class Alias(models.Model):
|
||||
address = models.CharField(max_length=100)
|
||||
mbox = models.ForeignKey(Mailbox)
|
||||
enabled = models.BooleanField()
|
||||
@@ -0,0 +1,36 @@
|
||||
from django import template
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.simple_tag
|
||||
def domain_menu(domain_id, selection):
|
||||
return render_to_string('admin/domain_menu.html',
|
||||
{"selection" : selection,
|
||||
"domain_id" : domain_id})
|
||||
|
||||
|
||||
# class MyVar(template.Node):
|
||||
# def __init__(self, value, var_name):
|
||||
# self.var_name = var_name
|
||||
# self.value = value
|
||||
|
||||
# def render(self, context):
|
||||
# context[self.var_name] = self.value
|
||||
# return ""
|
||||
|
||||
# import re
|
||||
|
||||
# @register.tag(name="var")
|
||||
# def do_my_var(parser, token):
|
||||
# try:
|
||||
# tag_name, arg = token.contents.split(None, 1)
|
||||
# except ValueError:
|
||||
# raise template.TemplateSyntaxError, '%r tag requires arguments' \
|
||||
# % token.contents.split()[0]
|
||||
# m = re.search('(.*?) as (\w+)', arg)
|
||||
# if not m:
|
||||
# raise template.TemplateSyntaxError, "%r tag had invalid arguments" \
|
||||
# % tag_name
|
||||
# value, var_name = m.groups()
|
||||
# return MyVar(value, var_name)
|
||||
@@ -0,0 +1,18 @@
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('mailng.admin.views',
|
||||
(r'^$', 'domains'),
|
||||
(r'^domains/$', 'domains'),
|
||||
(r'^domains/new/', 'newdomain'),
|
||||
(r'^domains/(?P<dom_id>\d+)/edit/$', 'editdomain'),
|
||||
(r'^domains/(?P<dom_id>\d+)/delete/$', 'deldomain'),
|
||||
(r'^domains/(?P<dom_id>\d+)/newmailbox/$', 'newmailbox'),
|
||||
(r'^domains/(?P<dom_id>\d+)/editmailbox/(?P<mbox_id>\d+)/$', 'editmailbox'),
|
||||
(r'^domains/(?P<dom_id>\d+)/deletemailbox/(?P<mbox_id>\d+)/$', 'delmailbox'),
|
||||
(r'^domains/(?P<dom_id>\d+)/newalias/(?P<mbox_id>\d+)/$', 'newalias'),
|
||||
(r'^domains/(?P<dom_id>\d+)/editalias/(?P<alias_id>\d+)/$', 'editalias'),
|
||||
(r'^domains/(?P<dom_id>\d+)/$', 'mailboxes'),
|
||||
url(r'^domains/(?P<dom_id>\d+)/aliases/$', "aliases", name="full-aliases"),
|
||||
url(r'^domains/(?P<dom_id>\d+)/aliases/(?P<mbox_id>\d+)/$', "aliases", name="mbox-aliases"),
|
||||
(r'^domains/(?P<dom_id>\d+)/delalias/(?P<alias_id>\d+)/$', 'delalias'),
|
||||
)
|
||||
@@ -0,0 +1,222 @@
|
||||
from django.shortcuts import get_object_or_404, render_to_response
|
||||
from django.template.loader import render_to_string
|
||||
from django.template import RequestContext
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.utils import simplejson
|
||||
from django.core import serializers
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.models import User
|
||||
from mailng import admin
|
||||
from mailng.admin.models import Domain, Mailbox, Alias
|
||||
from forms import MailboxForm, DomainForm, AliasForm
|
||||
|
||||
def _ctx_ok(url):
|
||||
return {"status" : "ok", "url" : url}
|
||||
|
||||
def _ctx_ko(tpl, ctx):
|
||||
return {"status" : "ko", "content" : render_to_string(tpl, ctx)}
|
||||
|
||||
def _render(request, tpl, user_context):
|
||||
return render_to_response(tpl, user_context,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
@login_required
|
||||
def domains(request):
|
||||
domains = Domain.objects.all()
|
||||
counters = {}
|
||||
for dom in domains:
|
||||
dom.mboxcounter = len(dom.mailbox_set.all())
|
||||
return _render(request, 'admin/domains.html', {
|
||||
"domains" : domains, "counters" : counters
|
||||
})
|
||||
|
||||
@login_required
|
||||
def newdomain(request):
|
||||
if request.method == "POST":
|
||||
form = DomainForm(request.POST)
|
||||
error = None
|
||||
if form.is_valid():
|
||||
if Domain.objects.filter(name=request.POST["name"]):
|
||||
error = "Domain with this name already defined"
|
||||
else:
|
||||
form.save()
|
||||
ctx = _ctx_ok(reverse(admin.views.domains))
|
||||
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
|
||||
ctx = _ctx_ko("admin/newdomain.html", {
|
||||
"form" : form, "error" : error
|
||||
})
|
||||
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
|
||||
|
||||
form = DomainForm()
|
||||
return render_to_response('admin/newdomain.html', {
|
||||
"form" : form
|
||||
})
|
||||
@login_required
|
||||
def editdomain(request, dom_id):
|
||||
domain = Domain.objects.get(pk=dom_id)
|
||||
if request.method == "POST":
|
||||
form = DomainForm(request.POST, instance=domain)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
ctx = _ctx_ok(reverse(admin.views.domains))
|
||||
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
|
||||
ctx = _ctx_ko("admin/editdomain.html", {
|
||||
"domain" : domain, "form" : form
|
||||
})
|
||||
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
|
||||
|
||||
form = DomainForm(instance=domain)
|
||||
return render_to_response('admin/editdomain.html', {
|
||||
"domain" : domain, "form" : form
|
||||
})
|
||||
|
||||
@login_required
|
||||
def deldomain(request, dom_id):
|
||||
domain = Domain.objects.get(pk=dom_id)
|
||||
domain.delete()
|
||||
return HttpResponseRedirect('/mailng/admin/')
|
||||
|
||||
@login_required
|
||||
def mailboxes(request, dom_id=None):
|
||||
domain = Domain.objects.get(pk=dom_id)
|
||||
mailboxes = Mailbox.objects.filter(domain=dom_id)
|
||||
return _render(request, 'admin/mailboxes.html', {
|
||||
"mailboxes" : mailboxes, "domain" : domain
|
||||
})
|
||||
|
||||
@login_required
|
||||
def newmailbox(request, dom_id=None):
|
||||
domain = Domain.objects.get(pk=dom_id)
|
||||
if request.method == "POST":
|
||||
form = MailboxForm(request.POST)
|
||||
error = None
|
||||
if form.is_valid():
|
||||
if Mailbox.objects.filter(address=request.POST["address"],
|
||||
domain=dom_id):
|
||||
error = "Mailbox with this address already exists"
|
||||
else:
|
||||
mb = form.save(commit=False)
|
||||
user = User()
|
||||
user.username = user.email = "%s@%s" % (mb.address, domain.name)
|
||||
user.set_password(request.POST["password1"])
|
||||
user.is_active = request.POST.has_key("enabled") \
|
||||
and True or False
|
||||
fname, lname = mb.name.split()
|
||||
user.first_name = fname
|
||||
|
||||
user.last_name = lname
|
||||
user.save()
|
||||
mb.user = user
|
||||
|
||||
mb.uid = mb.gid = 500
|
||||
mb.domain = domain
|
||||
mb.save()
|
||||
ctx = _ctx_ok(reverse(admin.views.mailboxes, args=[domain.id]))
|
||||
return HttpResponse(simplejson.dumps(ctx),
|
||||
mimetype="application/json")
|
||||
ctx = _ctx_ko("admin/newmailbox.html", {
|
||||
"form" : form, "domain" : domain, "error" : error
|
||||
})
|
||||
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
|
||||
|
||||
form = MailboxForm()
|
||||
return render_to_response('admin/newmailbox.html', {
|
||||
"domain" : domain, "form" : form
|
||||
})
|
||||
|
||||
@login_required
|
||||
def editmailbox(request, dom_id, mbox_id=None):
|
||||
mb = Mailbox.objects.get(pk=mbox_id)
|
||||
if request.method == "POST":
|
||||
form = MailboxForm(request.POST, instance=mb)
|
||||
if form.is_valid():
|
||||
if request.POST["enabled"] != mb.user.is_active \
|
||||
or request.POST["password1"] != mb.user.password:
|
||||
mb.user.is_active = request.POST["enabled"]
|
||||
mb.user.password = request.POST["password1"]
|
||||
mb.user.save()
|
||||
form.save()
|
||||
ctx = _ctx_ok(reverse(admin.views.mailboxes, args=[dom_id]))
|
||||
else:
|
||||
ctx = _ctx_ko("admin/editmailbox.html", {
|
||||
"mbox" : mb, "form" : form
|
||||
})
|
||||
json = simplejson.dumps(ctx)
|
||||
return HttpResponse(json, mimetype="application/json")
|
||||
|
||||
form = MailboxForm(instance=mb)
|
||||
form.fields['enabled'].initial = mb.user.is_active
|
||||
form.fields['password1'].initial = mb.user.password
|
||||
form.fields['password2'].initial = mb.user.password
|
||||
return _render(request, 'admin/editmailbox.html', {
|
||||
"form" : form, "mbox" : mb
|
||||
})
|
||||
|
||||
@login_required
|
||||
def delmailbox(request, dom_id, mbox_id=None):
|
||||
mb = Mailbox.objects.get(pk=mbox_id)
|
||||
mb.delete()
|
||||
return HttpResponseRedirect(reverse(admin.views.mailboxes,
|
||||
args=[dom_id]))
|
||||
|
||||
@login_required
|
||||
def aliases(request, dom_id=None, mbox_id=None):
|
||||
domain = Domain.objects.get(pk=dom_id)
|
||||
if not mbox_id:
|
||||
mboxes = Mailbox.objects.filter(domain=dom_id)
|
||||
aliases = []
|
||||
for mb in mboxes:
|
||||
aliases += Alias.objects.filter(mbox=mb.id)
|
||||
else:
|
||||
aliases = Alias.objects.filter(mbox=mbox_id)
|
||||
return _render(request, 'admin/aliases.html', {
|
||||
"aliases" : aliases, "domain" : domain
|
||||
})
|
||||
|
||||
@login_required
|
||||
def newalias(request, dom_id, mbox_id):
|
||||
mbox = Mailbox.objects.get(pk=mbox_id)
|
||||
if request.method == "POST":
|
||||
form = AliasForm(request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
ctx = _ctx_ok(reverse(admin.views.aliases, args=[mbox.domain.id]))
|
||||
else:
|
||||
ctx = _ctx_ko("admin/newalias.html", {
|
||||
"mbox" : mbox, "form" : form
|
||||
})
|
||||
json = simplejson.dumps(ctx)
|
||||
return HttpResponse(json, mimetype="application/json")
|
||||
|
||||
form = AliasForm({"mbox" : mbox_id}, domain=mbox.domain)
|
||||
return render_to_response('admin/newalias.html', {
|
||||
"mbox" : mbox, "form" : form, "noerrors" : True
|
||||
})
|
||||
|
||||
@login_required
|
||||
def editalias(request, dom_id, alias_id):
|
||||
alias = Alias.objects.get(pk=alias_id)
|
||||
if request.method == "POST":
|
||||
form = AliasForm(request.POST, instance=alias)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
ctx = _ctx_ok(reverse(admin.views.aliases, args=[dom_id]))
|
||||
else:
|
||||
ctx = _ctx_ko("admin/editalias.html", {
|
||||
"alias" : alias, "form" : form
|
||||
})
|
||||
json = simplejson.dumps(ctx)
|
||||
return HttpResponse(json, mimetype="application/json")
|
||||
form = AliasForm(instance=alias)
|
||||
return _render(request, 'admin/editalias.html', {
|
||||
"form" : form, "alias" : alias
|
||||
})
|
||||
|
||||
@login_required
|
||||
def delalias(request, dom_id, alias_id):
|
||||
alias = Alias.objects.get(pk=alias_id)
|
||||
alias.delete()
|
||||
return HttpResponseRedirect(reverse(admin.views.aliases,
|
||||
args=[dom_id]))
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
from django.core.management import execute_manager
|
||||
try:
|
||||
import settings # Assumed to be in the same directory.
|
||||
except ImportError:
|
||||
import sys
|
||||
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
execute_manager(settings)
|
||||
@@ -0,0 +1,82 @@
|
||||
# Django settings for mailng project.
|
||||
|
||||
DEBUG = False
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
||||
ADMINS = (
|
||||
# ('Your Name', 'your_email@domain.com'),
|
||||
)
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
|
||||
DATABASE_NAME = 'mailng' # Or path to database file if using sqlite3.
|
||||
DATABASE_USER = '' # Not used with sqlite3.
|
||||
DATABASE_PASSWORD = '' # Not used with sqlite3.
|
||||
DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
|
||||
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
# although not all choices may be available on all operating systems.
|
||||
# If running in a Windows environment this must be set to the same as your
|
||||
# system time zone.
|
||||
TIME_ZONE = 'America/Chicago'
|
||||
|
||||
# Language code for this installation. All choices can be found here:
|
||||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
# If you set this to False, Django will make some optimizations so as not
|
||||
# to load the internationalization machinery.
|
||||
USE_I18N = True
|
||||
|
||||
LOGIN_REDIRECT_URL = '/mailng/admin/'
|
||||
|
||||
# Absolute path to the directory that holds media.
|
||||
# Example: "/home/media/media.lawrence.com/"
|
||||
MEDIA_ROOT = ''
|
||||
|
||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||
# trailing slash if there is a path component (optional in other cases).
|
||||
# Examples: "http://media.lawrence.com", "http://example.com/media/"
|
||||
MEDIA_URL = ''
|
||||
|
||||
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
|
||||
# trailing slash.
|
||||
# Examples: "http://foo.com/media/", "/media/".
|
||||
ADMIN_MEDIA_PREFIX = '/media/'
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = '2)e+la#y$1b&v!p)s^&4lwpc92o59fye)mj^3^7$jytmvx379d'
|
||||
|
||||
# List of callables that know how to import templates from various sources.
|
||||
TEMPLATE_LOADERS = (
|
||||
'django.template.loaders.filesystem.load_template_source',
|
||||
'django.template.loaders.app_directories.load_template_source',
|
||||
# 'django.template.loaders.eggs.load_template_source',
|
||||
)
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'mailng.urls'
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
|
||||
# Always use forward slashes, even on Windows.
|
||||
# Don't forget to use absolute paths, not relative paths.
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'mailng.admin'
|
||||
)
|
||||
@@ -0,0 +1,384 @@
|
||||
/**
|
||||
* SqueezeBox - Expandable Lightbox
|
||||
*
|
||||
* Allows to open various content as modal,
|
||||
* centered and animated box.
|
||||
*
|
||||
* Dependencies: MooTools 1.2 trunk (04/2008)
|
||||
*
|
||||
* Inspired by
|
||||
* ... Lokesh Dhakar - The original Lightbox v2
|
||||
*
|
||||
* @version 1.1 rc2
|
||||
*
|
||||
* @license MIT-style license
|
||||
* @author Harald Kirschner <mail [at] digitarald.de>
|
||||
* @copyright Author
|
||||
*/
|
||||
var SqueezeBox = {
|
||||
|
||||
presets: {
|
||||
size: {x: 600, y: 450},
|
||||
sizeLoading: {x: 200, y: 150},
|
||||
marginInner: {x: 20, y: 20},
|
||||
marginImage: {x: 50, y: 75},
|
||||
handler: false,
|
||||
target: null,
|
||||
closable: true,
|
||||
closeBtn: true,
|
||||
zIndex: 65555,
|
||||
overlayOpacity: 0.7,
|
||||
classWindow: '',
|
||||
classOverlay: '',
|
||||
overlayFx: {},
|
||||
resizeFx: {},
|
||||
contentFx: {},
|
||||
parse: false, // 'rel'
|
||||
parseSecure: false,
|
||||
ajaxOptions: {},
|
||||
onOpen: $empty,
|
||||
onClose: $empty,
|
||||
onUpdate: $empty,
|
||||
onResize: $empty,
|
||||
onMove: $empty,
|
||||
onShow: $empty,
|
||||
onHide: $empty
|
||||
},
|
||||
|
||||
initialize: function(presets) {
|
||||
if (this.options) return this;
|
||||
this.presets = $merge(this.presets, presets);
|
||||
this.options = {};
|
||||
this.setOptions(this.presets).build();
|
||||
this.bound = {
|
||||
window: this.reposition.bind(this, [null]),
|
||||
scroll: this.checkTarget.bind(this),
|
||||
close: this.close.bind(this),
|
||||
key: this.onKey.bind(this)
|
||||
};
|
||||
this.isOpen = this.isLoading = false;
|
||||
return this;
|
||||
},
|
||||
|
||||
build: function() {
|
||||
this.overlay = new Element('div', {
|
||||
id: 'sbox-overlay',
|
||||
styles: {display: 'none', zIndex: this.options.zIndex}
|
||||
});
|
||||
this.content = new Element('div', {id: 'sbox-content'});
|
||||
this.closeBtn = new Element('a', {id: 'sbox-btn-close', href: '#'});
|
||||
this.win = new Element('div', {
|
||||
id: 'sbox-window',
|
||||
styles: {display: 'none', zIndex: this.options.zIndex + 2}
|
||||
}).adopt(this.closeBtn, this.content);
|
||||
this.fx = {
|
||||
overlay: new Fx.Tween(this.overlay, $merge({
|
||||
property: 'opacity',
|
||||
onStart: Events.prototype.clearChain,
|
||||
duration: 250,
|
||||
link: 'cancel'
|
||||
}, this.options.overlayFx)).set(0),
|
||||
win: new Fx.Morph(this.win, $merge({
|
||||
onStart: Events.prototype.clearChain,
|
||||
unit: 'px',
|
||||
duration: 750,
|
||||
transition: Fx.Transitions.Quint.easeOut,
|
||||
link: 'cancel',
|
||||
unit: 'px'
|
||||
}, this.options.resizeFx)),
|
||||
content: new Fx.Tween(this.content, $merge({
|
||||
property: 'opacity',
|
||||
duration: 250,
|
||||
link: 'cancel'
|
||||
}, this.options.contentFx)).set(0)
|
||||
};
|
||||
$(document.body).adopt(this.overlay, this.win);
|
||||
},
|
||||
|
||||
assign: function(to, options) {
|
||||
return to.addEvent('click', function() {
|
||||
return !SqueezeBox.fromElement(this, options);
|
||||
});
|
||||
},
|
||||
|
||||
fromElement: function(from, options) {
|
||||
this.initialize();
|
||||
if (this.element) this.trash();
|
||||
this.element = $(from);
|
||||
this.setOptions($merge(this.presets, options || {}));
|
||||
if (this.element && this.options.parse) {
|
||||
var obj = this.element.getProperty(this.options.parse);
|
||||
if (obj && (obj = JSON.decode(obj, this.options.parseSecure))) this.setOptions(obj);
|
||||
}
|
||||
this.assignOptions();
|
||||
this.url = ((this.element) ? (this.options.url || this.element.get('href')) : from) || '';
|
||||
var handler = this.options.handler;
|
||||
if (handler) return this.setContent(handler, this.parsers[handler].call(this, true));
|
||||
var ret = false;
|
||||
this.parsers.some(function(parser, key) {
|
||||
var content = parser.call(this);
|
||||
if (content) {
|
||||
ret = this.setContent(key, content);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, this);
|
||||
return ret;
|
||||
},
|
||||
|
||||
assignOptions: function() {
|
||||
this.overlay.set('class', this.options.classOverlay);
|
||||
this.win.set('class', this.options.classWindow);
|
||||
if (Browser.Engine.trident4) this.win.addClass('sbox-window-ie6');
|
||||
},
|
||||
|
||||
close: function(e) {
|
||||
var stoppable = ($type(e) == 'event');
|
||||
if (stoppable) e.stop();
|
||||
if (!this.isOpen || (stoppable && !$lambda(this.options.closable).call(this, e))) return this;
|
||||
this.fx.overlay.start(0).chain(this.toggleOverlay.bind(this));
|
||||
this.win.setStyle('display', 'none');
|
||||
this.toggleListeners();
|
||||
this.isOpen = false;
|
||||
this.fireEvent('onClose', [this.content]);
|
||||
this.trash();
|
||||
return this;
|
||||
},
|
||||
|
||||
trash: function() {
|
||||
this.element = this.asset = null;
|
||||
this.options = {};
|
||||
this.removeEvents().setOptions(this.presets).callChain();
|
||||
},
|
||||
|
||||
onError: function() {
|
||||
this.asset = null;
|
||||
this.setContent('string', 'Error during loading');
|
||||
},
|
||||
|
||||
setContent: function(handler, content) {
|
||||
if (!this.handlers[handler]) return false;
|
||||
this.content.className = 'sbox-content-' + handler;
|
||||
this.applyTimer = this.applyContent.delay(this.fx.overlay.options.duration, this, this.handlers[handler].call(this, content));
|
||||
if (this.overlay.retrieve('opacity')) return this;
|
||||
this.toggleOverlay(true);
|
||||
this.fx.overlay.start(this.options.overlayOpacity);
|
||||
return this.reposition();
|
||||
},
|
||||
|
||||
applyContent: function(content, size) {
|
||||
this.applyTimer = $clear(this.applyTimer);
|
||||
this.hideContent();
|
||||
if (!content) {
|
||||
this.toggleLoading(true);
|
||||
} else {
|
||||
if (this.isLoading) this.toggleLoading(false);
|
||||
this.fireEvent('onUpdate', [this.content], 20);
|
||||
}
|
||||
this.content.empty();
|
||||
if (['string', 'array', false].contains($type(content))) this.content.set('html', content || '');
|
||||
else this.content.adopt(content);
|
||||
this.callChain();
|
||||
if (!this.isOpen) {
|
||||
this.toggleListeners(true);
|
||||
this.resize(size, true);
|
||||
this.isOpen = true;
|
||||
this.fireEvent('onOpen', [this.content]);
|
||||
} else {
|
||||
this.resize(size);
|
||||
}
|
||||
},
|
||||
|
||||
resize: function(size, instantly) {
|
||||
var box = document.getSize(), scroll = document.getScroll();
|
||||
this.size = $merge((this.isLoading) ? this.options.sizeLoading : this.options.size, size);
|
||||
var to = {
|
||||
width: this.size.x,
|
||||
height: this.size.y,
|
||||
left: (scroll.x + (box.x - this.size.x - this.options.marginInner.x) / 2).toInt(),
|
||||
top: (scroll.y + (box.y - this.size.y - this.options.marginInner.y) / 2).toInt()
|
||||
};
|
||||
$clear(this.showTimer || null);
|
||||
this.hideContent();
|
||||
if (!instantly) {
|
||||
this.fx.win.start(to).chain(this.showContent.bind(this));
|
||||
} else {
|
||||
this.win.setStyles(to).setStyle('display', '');
|
||||
this.showTimer = this.showContent.delay(50, this);
|
||||
}
|
||||
return this.reposition();
|
||||
},
|
||||
|
||||
toggleListeners: function(state) {
|
||||
var fn = (state) ? 'addEvent' : 'removeEvent';
|
||||
this.closeBtn[fn]('click', this.bound.close);
|
||||
this.overlay[fn]('click', this.bound.close);
|
||||
document[fn]('keydown', this.bound.key)[fn]('mousewheel', this.bound.scroll);
|
||||
window[fn]('resize', this.bound.window)[fn]('scroll', this.bound.window);
|
||||
},
|
||||
|
||||
toggleLoading: function(state) {
|
||||
this.isLoading = state;
|
||||
this.win[(state) ? 'addClass' : 'removeClass']('sbox-loading');
|
||||
if (state) this.fireEvent('onLoading', [this.win]);
|
||||
},
|
||||
|
||||
toggleOverlay: function(state) {
|
||||
this.overlay.setStyle('display', (state) ? '' : 'none');
|
||||
$(document.body)[(state) ? 'addClass' : 'removeClass']('body-overlayed');
|
||||
},
|
||||
|
||||
showContent: function() {
|
||||
if (this.content.get('opacity')) this.fireEvent('onShow', [this.win]);
|
||||
this.fx.content.start(1);
|
||||
},
|
||||
|
||||
hideContent: function() {
|
||||
if (!this.content.get('opacity')) this.fireEvent('onHide', [this.win]);
|
||||
this.fx.content.set(0);
|
||||
},
|
||||
|
||||
onKey: function(e) {
|
||||
switch (e.key) {
|
||||
case 'esc': this.close(e);
|
||||
case 'up': case 'down': return false;
|
||||
}
|
||||
},
|
||||
|
||||
checkTarget: function(e) {
|
||||
return this.content.hasChild(e.target);
|
||||
},
|
||||
|
||||
reposition: function() {
|
||||
var size = document.getSize(), scroll = document.getScroll();
|
||||
this.overlay.setStyles({
|
||||
left: scroll.x + 'px',
|
||||
top: scroll.y + 'px',
|
||||
width: size.x + 'px',
|
||||
height: size.y + 'px'
|
||||
});
|
||||
this.win.setStyles({
|
||||
left: (scroll.x + (size.x - this.win.offsetWidth) / 2).toInt() + 'px',
|
||||
top: (scroll.y + (size.y - this.win.offsetHeight) / 2).toInt() + 'px'
|
||||
});
|
||||
return this.fireEvent('onMove', [this.overlay, this.win]);
|
||||
},
|
||||
|
||||
removeEvents: function(type){
|
||||
if (!this.$events) return this;
|
||||
if (!type) this.$events = null;
|
||||
else if (this.$events[type]) this.$events[type] = null;
|
||||
return this;
|
||||
},
|
||||
|
||||
extend: function(properties) {
|
||||
return $extend(this, properties);
|
||||
},
|
||||
|
||||
handlers: new Hash(),
|
||||
|
||||
parsers: new Hash()
|
||||
|
||||
};
|
||||
|
||||
SqueezeBox.extend(new Events($empty)).extend(new Options($empty)).extend(new Chain($empty));
|
||||
|
||||
SqueezeBox.parsers.extend({
|
||||
|
||||
image: function(preset) {
|
||||
return (preset || (/\.(?:jpg|png|gif)$/i).test(this.url)) ? this.url : false;
|
||||
},
|
||||
|
||||
clone: function(preset) {
|
||||
if ($(this.options.target)) return $(this.options.target);
|
||||
if (this.element && !this.element.parentNode) return this.element;
|
||||
var bits = this.url.match(/#([\w-]+)$/);
|
||||
return (bits) ? $(bits[1]) : (preset ? this.element : false);
|
||||
},
|
||||
|
||||
ajax: function(preset) {
|
||||
return (preset || (this.url && !(/^(?:javascript|#)/i).test(this.url))) ? this.url : false;
|
||||
},
|
||||
|
||||
iframe: function(preset) {
|
||||
return (preset || this.url) ? this.url : false;
|
||||
},
|
||||
|
||||
string: function(preset) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
SqueezeBox.handlers.extend({
|
||||
|
||||
image: function(url) {
|
||||
var size, tmp = new Image();
|
||||
this.asset = null;
|
||||
tmp.onload = tmp.onabort = tmp.onerror = (function() {
|
||||
tmp.onload = tmp.onabort = tmp.onerror = null;
|
||||
if (!tmp.width) {
|
||||
this.onError.delay(10, this);
|
||||
return;
|
||||
}
|
||||
var box = document.getSize();
|
||||
box.x -= this.options.marginImage.x;
|
||||
box.y -= this.options.marginImage.y;
|
||||
size = {x: tmp.width, y: tmp.height};
|
||||
for (var i = 2; i--;) {
|
||||
if (size.x > box.x) {
|
||||
size.y *= box.x / size.x;
|
||||
size.x = box.x;
|
||||
} else if (size.y > box.y) {
|
||||
size.x *= box.y / size.y;
|
||||
size.y = box.y;
|
||||
}
|
||||
}
|
||||
size.x = size.x.toInt();
|
||||
size.y = size.y.toInt();
|
||||
this.asset = $(tmp);
|
||||
tmp = null;
|
||||
this.asset.setProperties({width: size.x, height: size.y});
|
||||
if (this.isOpen) this.applyContent(this.asset, size);
|
||||
}).bind(this);
|
||||
tmp.src = url;
|
||||
if (tmp && tmp.onload && tmp.complete) tmp.onload();
|
||||
return (this.asset) ? [this.asset, size] : null;
|
||||
},
|
||||
|
||||
clone: function(el) {
|
||||
return el.clone();
|
||||
},
|
||||
|
||||
adopt: $arguments(0),
|
||||
|
||||
ajax: function(url) {
|
||||
this.asset = new Request.HTML($merge({
|
||||
method: 'get'
|
||||
}, this.options.ajaxOptions)).addEvents({
|
||||
onSuccess: function(resp) {
|
||||
this.applyContent(resp);
|
||||
this.asset = null;
|
||||
}.bind(this),
|
||||
onFailure: this.onError.bind(this)
|
||||
});
|
||||
this.asset.send.delay(10, this.asset, [{url: url}]);
|
||||
},
|
||||
|
||||
iframe: function(url) {
|
||||
return new Element('iframe', $merge({
|
||||
src: url,
|
||||
frameBorder: 0,
|
||||
width: this.options.size.x,
|
||||
height: this.options.size.y
|
||||
}, this.options.iframeOptions));
|
||||
},
|
||||
|
||||
string: function(str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
SqueezeBox.handlers.url = SqueezeBox.handlers.ajax;
|
||||
SqueezeBox.parsers.url = SqueezeBox.parsers.ajax;
|
||||
SqueezeBox.parsers.adopt = SqueezeBox.parsers.clone;
|
||||
@@ -0,0 +1,92 @@
|
||||
|
||||
window.addEvent('domready', function() {
|
||||
var handlers = new Array();
|
||||
|
||||
// handlers['loadDom'] = function(obj, target) {
|
||||
/* $$('a[name=loadDom]').setStyles({'color' : '#999'});*/
|
||||
/* obj.setStyles({"color": "black"});*/
|
||||
// loadPage(target, "content", null);
|
||||
// };
|
||||
|
||||
// handlers['loadContent'] = function(obj, target) {
|
||||
// loadPage(target, "content", null);
|
||||
// };
|
||||
|
||||
if ($$("a[name=deleteDom]"))
|
||||
$$("a[name=deleteDom]").addEvent('click', function(event) {
|
||||
if (!confirm("Delete this domain?"))
|
||||
event.stop();
|
||||
});
|
||||
|
||||
if ($$("a[name=deleteMb]"))
|
||||
$$("a[name=deleteMb]").addEvent('click', function(event) {
|
||||
if (!confirm("Delete this mailbox?"))
|
||||
event.stop();
|
||||
});
|
||||
|
||||
if ($$("a[name=deleteAlias]"))
|
||||
$$("a[name=deleteAlias]").addEvent('click', function(event) {
|
||||
if (!confirm("Delete this alias?"))
|
||||
event.stop();
|
||||
});
|
||||
|
||||
handlers['deleteDom'] = function(obj, target) {
|
||||
return confirm("Supprimer ce domaine?");
|
||||
}
|
||||
|
||||
$('body').addEvent('click', function(event) {
|
||||
target = event.target;
|
||||
if (target.get('tag') == 'a') {
|
||||
name = target.get('name');
|
||||
if (name == 'undefined')
|
||||
return;
|
||||
if (typeof(handlers[name]) != 'undefined') {
|
||||
if (!handlers[name](target, target.get('href'))) {
|
||||
new Event(event).stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('body').addEvent('submit', function(event) {
|
||||
alert("newodm submit");
|
||||
target = event.target;
|
||||
if (target.get('tag') == 'form') {
|
||||
name = target.get('name');
|
||||
if (name == 'undefined')
|
||||
return;
|
||||
if (typeof(handlers[name]) != 'undefined') {
|
||||
new Event(event).stop();
|
||||
handlers[name](target);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
SqueezeBox.assign($$('a.boxed'), {
|
||||
//size: {x:300, y:180}
|
||||
parse: 'rel',
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
newdom = function() {
|
||||
alert("pouet");
|
||||
form = $("form[name=newdom]");
|
||||
var params = obj.toQueryString();
|
||||
form.set('send', {
|
||||
onSuccess: function(response) {
|
||||
SqueezeBox.loadModal(obj.action + '?' + params);
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
|
||||
loadPage = function(url, destination, callback) {
|
||||
var destination = (destination == null) ? "page" : destination;
|
||||
|
||||
if (callback)
|
||||
new Request({url: url, method: "get", onSuccess: callback}).send();
|
||||
else
|
||||
new Request({url: url, method: "get", onSuccess: function(data) {
|
||||
$(destination).set('html', data);
|
||||
}}).send();
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
window.addEvent("domready", function() {
|
||||
sqbsubmit = function(obj, dest, id, callback) {
|
||||
obj.set('send', {
|
||||
onSuccess: function(responseText) {
|
||||
response = JSON.decode(responseText);
|
||||
if (response.status == "ko") {
|
||||
$(dest).set("html", response.content);
|
||||
$(id).addEvent("submit", callback);
|
||||
} else {
|
||||
parent.SqueezeBox.close();
|
||||
parent.location.href = response.url;
|
||||
}
|
||||
}
|
||||
});
|
||||
obj.send();
|
||||
}
|
||||
|
||||
generic_submit = function(obj, event, id, callback) {
|
||||
event.stop();
|
||||
sqbsubmit(obj, "content", id, callback);
|
||||
}
|
||||
domain_submit = function(event) {
|
||||
generic_submit(this, event, "domform", domain_submit);
|
||||
}
|
||||
mailbox_submit = function(event) {
|
||||
generic_submit(this, event, "mboxform", mailbox_submit);
|
||||
}
|
||||
alias_submit = function(event) {
|
||||
generic_submit(this, event, "aliasform", alias_submit);
|
||||
}
|
||||
|
||||
if ($("domform"))
|
||||
$("domform").addEvent("submit", domain_submit);
|
||||
|
||||
if ($("mboxform"))
|
||||
$("mboxform").addEvent("submit", mailbox_submit);
|
||||
|
||||
if ($("aliasform"))
|
||||
$("aliasform").addEvent("submit", alias_submit);
|
||||
});
|
||||
|
After Width: | Height: | Size: 323 B |
|
After Width: | Height: | Size: 611 B |
|
After Width: | Height: | Size: 681 B |
|
After Width: | Height: | Size: 858 B |
|
After Width: | Height: | Size: 574 B |
|
After Width: | Height: | Size: 799 B |
|
After Width: | Height: | Size: 619 B |
|
After Width: | Height: | Size: 518 B |
|
After Width: | Height: | Size: 611 B |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 655 B |
|
After Width: | Height: | Size: 650 B |
@@ -0,0 +1,78 @@
|
||||
#sbox-window embed, #sbox-window object, #sbox-window select
|
||||
{
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#sbox-overlay
|
||||
{
|
||||
position: absolute;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
#sbox-window
|
||||
{
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
text-align: left;
|
||||
overflow: visible;
|
||||
padding: 10px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
}
|
||||
|
||||
#sbox-btn-close
|
||||
{
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
right: -15px;
|
||||
top: -15px;
|
||||
background: url(closebox.png) no-repeat center;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.sbox-window-ie6 #sbox-btn-close
|
||||
{
|
||||
background-image: url(closebox.gif);
|
||||
}
|
||||
|
||||
.sbox-loading #sbox-content
|
||||
{
|
||||
background-image: url(spinner.gif);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
#sbox-content
|
||||
{
|
||||
clear: both;
|
||||
overflow: auto;
|
||||
background-color: #fff;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sbox-content-image#sbox-content
|
||||
{
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
#sbox-image
|
||||
{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sbox-content-image img
|
||||
{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sbox-content-iframe#sbox-content
|
||||
{
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.body-overlayed embed, .body-overlayed object, .body-overlayed select
|
||||
{
|
||||
visibility: hidden;
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
body {
|
||||
font-family: arial, helvetica, verdana, tahoma, sans-serif;
|
||||
font-size: small;
|
||||
background: #153F65;
|
||||
width: 950px;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#header {
|
||||
width: 100%;
|
||||
height: 120px;
|
||||
background: #072342;
|
||||
margin-top: 20px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
color: white;
|
||||
}
|
||||
|
||||
#header h2 {
|
||||
margin-left: 20px;
|
||||
color: #6AB0C5;
|
||||
}
|
||||
|
||||
#header h3 {
|
||||
margin: 0 0 5px 0;
|
||||
text-align: center;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
#logo {
|
||||
float: left;
|
||||
margin-top: 20px;
|
||||
background: url(logo.png) left no-repeat;
|
||||
height: 90px;
|
||||
line-height: 90px;
|
||||
min-width: 90px;
|
||||
width: expression(document.body.clientWidth < 1280 ? "90px" : "15%");
|
||||
}
|
||||
|
||||
#title {
|
||||
float: left;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#info {
|
||||
float: right;
|
||||
text-align: center;
|
||||
background: white;
|
||||
width: 150px;
|
||||
margin: 20px 20px;
|
||||
padding: 10px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
#body {
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin: 15px 0;
|
||||
/*height: 600px;*/
|
||||
}
|
||||
|
||||
#loginbox {
|
||||
margin: 50px auto;
|
||||
width: 300px;
|
||||
padding-bottom: 15px;
|
||||
border: 1px solid #ddd;
|
||||
background: white;
|
||||
}
|
||||
|
||||
#loginbox h3 {
|
||||
font-size: small;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#leftcol {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.leftbox {
|
||||
border: 1px solid #333;
|
||||
background: white;
|
||||
}
|
||||
|
||||
#menubox {
|
||||
width: 170px;
|
||||
}
|
||||
|
||||
#userbox {
|
||||
width: 170px;
|
||||
}
|
||||
|
||||
.leftbox h3 {
|
||||
font-size: small;
|
||||
margin: 2px 0px 2px 0px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.leftbox ul {
|
||||
list-style: none;
|
||||
padding: 5px 5px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.leftbox li {
|
||||
clear: both;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.leftbox a:link, .leftbox a:visited {
|
||||
background: transparent;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.leftbox a:hover {
|
||||
color: #6AB0C5;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.leftbox img {
|
||||
float: left;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
#content {
|
||||
float: right;
|
||||
width: 750px;
|
||||
height: 400px;
|
||||
background: white;
|
||||
border: 1px solid #333;
|
||||
padding: 5px;
|
||||
margin: 0 0 0 15px;
|
||||
}
|
||||
|
||||
#menubar {
|
||||
margin-left: 20px;
|
||||
display: table;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.menu2 {
|
||||
font-size: 95%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.menu2 ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.menu2 li {
|
||||
float: left;
|
||||
display: inline;
|
||||
margin: 2px 5px;
|
||||
}
|
||||
|
||||
.menu2 li.selected {
|
||||
/* text-decoration: underline;*/
|
||||
background: #ffffcc;
|
||||
}
|
||||
|
||||
.menu2 a:link, .menu2 a:visited {
|
||||
background: transparent;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.menu2 a:hover {
|
||||
color: #6AB0C5;
|
||||
}
|
||||
|
||||
.menu2 img {
|
||||
float: left;
|
||||
margin: 1px 3px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
border-top: 1px solid #333;
|
||||
text-align: center;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.title {
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.title img {
|
||||
float: left;
|
||||
margin: 1px 3px;;
|
||||
}
|
||||
|
||||
.title h1 {
|
||||
float: left;
|
||||
margin: 5px 10px;
|
||||
font-size: medium;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#body table {
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 20px;
|
||||
}
|
||||
|
||||
#body tr.odd {
|
||||
background: #F7F9Fb;
|
||||
}
|
||||
|
||||
#body tr.even {
|
||||
background: white;
|
||||
}
|
||||
|
||||
#body table th {
|
||||
background: #CEDBEC;
|
||||
text-align: left;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#body table th.right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#body table td {
|
||||
border-bottom: 1px solid #C8D6E8;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#body a, a:visited {
|
||||
color: #2a4069;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#body a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#domcontent {
|
||||
margin: 10px auto;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
|
||||
.button {
|
||||
margin-left: 35px;
|
||||
}
|
||||
|
||||
.button img {
|
||||
float: left;
|
||||
margin: 0px 3px;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: medium;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
body {
|
||||
font-family: arial, helvetica, verdana, tahoma, sans-serif;
|
||||
font-size: small;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.row {
|
||||
clear: both;
|
||||
padding-top: 10px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
div.row label {
|
||||
float: left;
|
||||
width: 120px;
|
||||
font-size: small;
|
||||
padding: 3px 0;
|
||||
}
|
||||
|
||||
form input {
|
||||
border: 1px solid #cccccc;
|
||||
color: inherit;
|
||||
/*background-color: #e9e9e9;*/
|
||||
background-color: #eee;
|
||||
width: 120px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
form input:hover {
|
||||
color: inherit;
|
||||
background-color: #ffffcc;
|
||||
}
|
||||
|
||||
.title {
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.title img {
|
||||
float: left;
|
||||
margin: 1px 3px;;
|
||||
}
|
||||
|
||||
.title h1 {
|
||||
float: left;
|
||||
margin: 5px 10px;
|
||||
font-size: medium;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.lastrow {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.errorlist ul {
|
||||
float: left;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.errorlist li {
|
||||
margin-left: 10px;
|
||||
float: left;
|
||||
display: inline;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.error {
|
||||
margin-left: 20px;
|
||||
color: red;
|
||||
font-size: small;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 495 B |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,38 @@
|
||||
{% extends "admin/domain_header.html" %}
|
||||
{% block menu %}
|
||||
{% load admin_extras %}
|
||||
{% domain_menu domain.id "aliases" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block domcontent %}
|
||||
{% if not aliases %}
|
||||
<p>No alias defined.</p>
|
||||
{% else %}
|
||||
<table>
|
||||
<tr>
|
||||
<th width="50px">Actions</th>
|
||||
<th width="150px">Address</th>
|
||||
<th width="200px">Mailbox</th>
|
||||
<th width="75px">Enabled</th>
|
||||
</tr>
|
||||
{% for alias in aliases %}
|
||||
<tr>
|
||||
<td>
|
||||
{% url admin.views.editalias domain.id alias.id as edit_url %}
|
||||
<a href="{{ edit_url }}" class="boxed"
|
||||
rel="{handler:'iframe',size:{x:300,y:190}}">
|
||||
<img src="/static/pics/edit.png" border="0" title="Edit alias"/>
|
||||
</a>
|
||||
<a href="{{ del_url }}" name="deleteAlias">
|
||||
<img src="/static/pics/remove.png" border="0" title="Delete alias" />
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ alias.address }}@{{ alias.mbox.domain.name }}</td>
|
||||
<td>{{ alias.mbox.address }}@{{ alias.mbox.domain.name }}</td>
|
||||
<td>{{ alias.enabled|yesno }}</td
|
||||
{% url admin.views.delalias domain.id alias.id as del_url %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,17 @@
|
||||
{% extends "admin/layout.html" %}
|
||||
{% block html_head %}
|
||||
<script src="/static/js/domains.js" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
{% block mainframe %}
|
||||
<div class="header">
|
||||
<h1>Domain {{ domain.name }}</h1>
|
||||
</div>
|
||||
|
||||
<div id="menubar" class="menu2">
|
||||
{% block menu %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<div id="domcontent">
|
||||
{% block domcontent %}{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,27 @@
|
||||
{% url admin.views.editdomain domain_id as edit_url %}
|
||||
{% url admin.views.newmailbox domain_id as new_url %}
|
||||
{% url admin.views.mailboxes domain_id as mboxes_url %}
|
||||
{% url full-aliases domain_id as aliases_url %}
|
||||
<ul>
|
||||
{% url admin.views.newmailbox domain.id as newmb_url %}
|
||||
<li>
|
||||
<a href="{{ new_url }}"
|
||||
class="boxed" rel="{handler:'iframe',size:{x:300,y:280}}">
|
||||
<img src="/static/pics/add.png" border="0" />
|
||||
New mailbox
|
||||
</a>
|
||||
</li>
|
||||
<li {% ifequal selection "mailboxes" %}class="selected"{% endifequal %}>
|
||||
<a href="{{ mboxes_url }}">
|
||||
<img src="/static/pics/mailbox.png" border="0"/>
|
||||
Mailboxes</a></li>
|
||||
<li {% ifequal selection "aliases" %}class="selected"{% endifequal %}>
|
||||
<a href="{{ aliases_url }}">
|
||||
<img src="/static/pics/alias.png" border="0"/>
|
||||
Aliases</a></li>
|
||||
<li>
|
||||
<a href="{{ edit_url }}" class="boxed"
|
||||
rel="{handler:'iframe',size:{x:300,y:180}}">
|
||||
<img src="/static/pics/edit.png" border="0"/>
|
||||
Properties</a></li>
|
||||
</ul>
|
||||
@@ -0,0 +1,45 @@
|
||||
{% extends "admin/layout.html" %}
|
||||
{% block html_head %}
|
||||
<script src="/static/js/domains.js" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
{% block mainframe %}
|
||||
<div class="header">
|
||||
<h1>Available domains</h1>
|
||||
</div>
|
||||
|
||||
<div id="domcontent">
|
||||
{% if not domains %}
|
||||
No domain defined.
|
||||
{% else %}
|
||||
<table>
|
||||
<tr>
|
||||
<th width="50px">Actions</th>
|
||||
<th width="80px">Name</th>
|
||||
<th width="50px">Mailboxes</th>
|
||||
<th width="50px">Quota</th>
|
||||
<th width="50px">Enabled</th>
|
||||
</tr>
|
||||
{% for dom in domains %}
|
||||
<tr class="{% cycle 'odd' 'even' %}">
|
||||
<td>
|
||||
{% url admin.views.editdomain dom.id as edit_url %}
|
||||
<a href="{{ edit_url }}" class="boxed"
|
||||
rel="{handler:'iframe',size:{x:300,y:180}}">
|
||||
<img src="/static/pics/edit.png" border="0" title="Edit domain"/>
|
||||
</a>
|
||||
{% url admin.views.deldomain dom.id as del_url %}
|
||||
<a href="{{ del_url }}" name="deleteDom">
|
||||
<img src="/static/pics/remove.png" border="0" title="Delete domain"/>
|
||||
</a>
|
||||
</td>
|
||||
{% url admin.views.mailboxes dom.id as domurl %}
|
||||
<td><a name="loadDom" href="{{ domurl }}">{{ dom.name }}</a></td>
|
||||
<td>{{ dom.mboxcounter }}</td>
|
||||
<td>{{ dom.quota }} MB</td>
|
||||
<td>{{ dom.enabled|yesno }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,15 @@
|
||||
{% extends "admin/layout_simple.html" %}
|
||||
{% block html_head %}
|
||||
<script src="/static/js/form.js" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>Alias {{ alias.address }}</h1></div>
|
||||
{% url admin.views.editalias alias.mbox.domain.id alias.id as edit_url %}
|
||||
<form action="{{ edit_url }}" method="POST" id="aliasform" name="aliasform">
|
||||
{% include "admin/genericform.html" %}
|
||||
<div class="spacer"></div>
|
||||
<div class="lastrow" align="center">
|
||||
<input type="submit" name="submit" value="Update" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,16 @@
|
||||
{% extends "admin/layout_simple.html" %}
|
||||
{% block html_head %}
|
||||
<script src="/static/js/form.js" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>Domain {{ domain.name }}</h1></div>
|
||||
|
||||
{% url admin.views.editdomain domain.id as dom_url %}
|
||||
<form action="{{ dom_url }}" method="post" name="domform" id="domform">
|
||||
{% include "admin/genericform.html" %}
|
||||
|
||||
<div class="lastrow" align="center">
|
||||
<input type="submit" class="button" name="submit" value="Update" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,17 @@
|
||||
{% extends "admin/layout_simple.html" %}
|
||||
{% block html_head %}
|
||||
<script src="/static/js/form.js" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>Mailbox {{ mbox.name }}</h1></div>
|
||||
|
||||
{% url admin.views.editmailbox mbox.domain_id mbox.id as box_url %}
|
||||
<form action="{{ box_url }}" method="POST" id="mboxform" name="mboxform">
|
||||
{% include "admin/genericform.html" %}
|
||||
<div class="spacer"></div>
|
||||
|
||||
<div class="lastrow" align="center">
|
||||
<input type="submit" name="submit" value="Update" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,5 @@
|
||||
{% for field in form %}
|
||||
<div class="row">
|
||||
{{ field.label_tag }} {{ field }} {% ifequal noerrors False %}{{ field.errors }}{% endifequal %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,12 @@
|
||||
{% extends "admin/layout.html" %}
|
||||
|
||||
{%block pagetitle %}Administration{%endblock %}
|
||||
{%block breadcrumb %}Domains{%endblock %}
|
||||
{% block html_head %}
|
||||
<script src="/static/js/domains.js" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
{% include default %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,48 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block content %}
|
||||
{% url admin.views.domains as dom_url %}
|
||||
<div id="body">
|
||||
<div id="leftcol">
|
||||
<div id="userbox" class="leftbox">
|
||||
{% if user.first_name %}
|
||||
<h3>{{ user.first_name }} {{ user.last_name }}</h3>
|
||||
{% else %}
|
||||
<h3>{{ user.username }}</h3>
|
||||
{% endif %}
|
||||
<ul>
|
||||
<li>
|
||||
{% url django.contrib.auth.views.logout_then_login as logout_url %}
|
||||
<a href="{{ logout_url }}">
|
||||
<img src="/static/pics/logout.png" border="0" />Logout</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/>
|
||||
<div id="menubox" class="leftbox">
|
||||
<ul>
|
||||
<li>
|
||||
{% url admin.views.newdomain as newdom_url %}
|
||||
<a href="{{ newdom_url }}" class="boxed"
|
||||
rel="{handler:'iframe',size:{x:300,y:200}}">
|
||||
<img src="/static/pics/add.png" border="0"/>
|
||||
New domain
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a name="loadContent" href="{{ dom_url }}">
|
||||
<img src="/static/pics/domains.png" border="0"/>
|
||||
Domains</a>
|
||||
</li>
|
||||
<li>
|
||||
<a name="loadContent" href="">
|
||||
<img src="/static/pics/settings.png" border="0"/>
|
||||
Settings</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
{%block mainframe %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/stylesheets/SqueezeBox.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/stylesheets/box.css" />
|
||||
<script src="/static/js/mootools.js" type="text/javascript"></script>
|
||||
<script src="/static/js/SqueezeBox.js" type="text/javascript"></script>
|
||||
{%block html_head %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="content">
|
||||
{%block content %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,22 @@
|
||||
{% extends "admin/layout.html" %}
|
||||
{% block html_head %}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="header">
|
||||
<h1>Mailbox {{ mbox.address }}@{{ mbox.domain.name }}</h1>
|
||||
</div>
|
||||
|
||||
<div id="menubar" class="menu2">
|
||||
{% block menu %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<div id="mboxcontent">
|
||||
<div class="row">
|
||||
<label>Name :</label><label>{{ mb.name }}</label>
|
||||
</div>
|
||||
|
||||
<h2>Aliases</h2>
|
||||
{% for alias in aliases %}
|
||||
{{ alias.address }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,50 @@
|
||||
{% extends "admin/domain_header.html" %}
|
||||
{% block menu %}
|
||||
{% load admin_extras %}
|
||||
{% domain_menu domain.id "mailboxes" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block domcontent %}
|
||||
{% if not mailboxes %}
|
||||
<p>No mailbox defined.</p>
|
||||
{% else %}
|
||||
<table>
|
||||
<tr>
|
||||
<th width="80px">Actions</th>
|
||||
<th width="130px">Name</th>
|
||||
<th width="170px">Address</th>
|
||||
<th width="60px">Quota</th>
|
||||
<th width="50px">Enabled</th>
|
||||
</tr>
|
||||
{% for mb in mailboxes %}
|
||||
<tr class="{% cycle 'odd' 'even' %}">
|
||||
<td>
|
||||
{% url admin.views.editmailbox domain.id mb.id as edit_url %}
|
||||
<a href="{{ edit_url }}" class="boxed"
|
||||
rel="{handler:'iframe',size:{x:300,y:280}}">
|
||||
<img src="/static/pics/edit.png" border="0" title="Edit mailbox"/>
|
||||
</a>
|
||||
{% url admin.views.delmailbox domain.id mb.id as del_url %}
|
||||
<a href="{{ del_url }}" name="deleteMb">
|
||||
<img src="/static/pics/remove.png" border="0"
|
||||
title="Delete mailbox" />
|
||||
</a>
|
||||
{% url admin.views.newalias domain.id mb.id as alias_url %}
|
||||
<a href="{{ alias_url }}" class="boxed"
|
||||
rel="{handler:'iframe',size:{x:300,y:190}}">
|
||||
<img src="/static/pics/add.png" border="0" title="Add new alias"/>
|
||||
</a>
|
||||
{% url mbox-aliases domain.id mb.id as aliases_url %}
|
||||
<a href="{{ aliases_url }}">
|
||||
<img src="/static/pics/alias.png" border="0" title="Mailbox aliases"/>
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ mb.name }}</td>
|
||||
<td>{{ mb.address }}@{{ mb.domain.name }}</td>
|
||||
<td>{{ mb.quota }} MB</td>
|
||||
<td>{{ mb.user.is_active|yesno }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,14 @@
|
||||
{% extends "admin/layout_simple.html" %}
|
||||
{% block html_head %}
|
||||
<script src="/static/js/form.js" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>Aliases for {{ mbox.address }}</h1></div>
|
||||
<p>
|
||||
<ul>
|
||||
{% for alias in aliases %}
|
||||
<li>{{alias.address}}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</p>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,15 @@
|
||||
{% extends "admin/layout_simple.html" %}
|
||||
{% block html_head %}
|
||||
<script src="/static/js/form.js" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>New alias</h1></div>
|
||||
{% url admin.views.newalias mbox.domain_id mbox.id as box_url %}
|
||||
<form action="{{ box_url }}" method="POST" id="aliasform" name="aliasform">
|
||||
{% include "admin/genericform.html" %}
|
||||
<div class="spacer"></div>
|
||||
<div class="lastrow" align="center">
|
||||
<input type="submit" name="submit" value="Create" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,18 @@
|
||||
{% extends "admin/layout_simple.html" %}
|
||||
{% block html_head %}
|
||||
<script src="/static/js/form.js" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>New domain</h1></div>
|
||||
|
||||
{% if error %}<div class="error">{{ error }}</div>{% endif %}
|
||||
{% url admin.views.newdomain as dom_url %}
|
||||
<form action="{{ dom_url }}" method="post" name="domform" id="domform">
|
||||
{% include "admin/genericform.html" %}
|
||||
|
||||
<div class="lastrow" align="center">
|
||||
<input type="submit" class="button" name="submit" value="Create" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
²
|
||||
@@ -0,0 +1,18 @@
|
||||
{% extends "admin/layout_simple.html" %}
|
||||
{% block html_head %}
|
||||
<script src="/static/js/form.js" type="text/javascript"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>New mailbox</h1></div>
|
||||
|
||||
{% if error %}<div class="error">{{ error }}</div>{% endif %}
|
||||
{% url admin.views.newmailbox domain.id as box_url %}
|
||||
<form action="{{ box_url }}" method="POST" id="mboxform" name="mboxform">
|
||||
{% include "admin/genericform.html" %}
|
||||
<div class="spacer"></div>
|
||||
|
||||
<div class="lastrow" align="center">
|
||||
<input type="submit" name="submit" value="Create" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>MailNG - {%block pagetitle %}{% endblock %}</title>
|
||||
<link rel="stylesheet" type="text/css" href="/static/stylesheets/basic.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/stylesheets/SqueezeBox.css" />
|
||||
<script src="/static/js/mootools.js" type="text/javascript"></script>
|
||||
<script src="/static/js/SqueezeBox.js" type="text/javascript"></script>
|
||||
{%block html_head %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="header" class="rounded">
|
||||
<div id="logo"></div>
|
||||
<div id="title">
|
||||
<h1>MailNG</h1>
|
||||
<h2>Simple web messaging solution</h2>
|
||||
|
||||
<div id="info"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
{%block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<div class="spacer"></div>
|
||||
|
||||
<div id="footer">
|
||||
© Antoine Nguyen 2009
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>MailNG - {%block pagetitle %}{% endblock %}</title>
|
||||
<link rel="stylesheet" type="text/css" href="/static/stylesheets/basic.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/stylesheets/SqueezeBox.css" />
|
||||
<script src="/static/js/mootools.js" type="text/javascript"></script>
|
||||
<script src="/static/js/SqueezeBox.js" type="text/javascript"></script>
|
||||
{%block html_head %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="header" class="rounded">
|
||||
<div id="logo"></div>
|
||||
<div id="title">
|
||||
<h1>MailNG</h1>
|
||||
<h2>Simple web messaging solution</h2>
|
||||
</div>
|
||||
</div>
|
||||
{% block content %}{% endblock %}
|
||||
<div class="spacer"></div>
|
||||
|
||||
<div id="footer">
|
||||
© Antoine Nguyen 2009
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,25 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block html_head %}
|
||||
<link rel="stylesheet" type="text/css" href="/static/stylesheets/box.css" />
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div id="loginbox">
|
||||
<h3>Welcome</h3>
|
||||
{% if form.errors %}
|
||||
<div class="error">
|
||||
<p>Your username and password didn't match. Please try again.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<form method="post" action=".">
|
||||
{% for field in form %}
|
||||
<div class="row">
|
||||
{{ field.label_tag }}{{ field }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="lastrow" align="center">
|
||||
<input type="submit" value="login" />
|
||||
</div>
|
||||
<input type="hidden" name="next" value="{{ next }}" />
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,29 @@
|
||||
from django.conf.urls.defaults import *
|
||||
from django.conf import settings
|
||||
|
||||
# Uncomment the next two lines to enable the admin:
|
||||
# from django.contrib import admin
|
||||
# admin.autodiscover()
|
||||
|
||||
urlpatterns = patterns('',
|
||||
# Example:
|
||||
# (r'^mailng/', include('mailng.foo.urls')),
|
||||
|
||||
# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
|
||||
# to INSTALLED_APPS to enable admin documentation:
|
||||
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),
|
||||
|
||||
# Uncomment the next line to enable the admin:
|
||||
# (r'^admin/(.*)', admin.site.root),
|
||||
|
||||
(r'^mailng/admin/', include('mailng.admin.urls')),
|
||||
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
|
||||
(r'^accounts/logout/$', 'django.contrib.auth.views.logout_then_login')
|
||||
)
|
||||
|
||||
if settings.DEBUG:
|
||||
urlpatterns += patterns(
|
||||
'',
|
||||
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/home/tonio/projets/mailng/static'})
|
||||
)
|
||||
|
||||