mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
* Added pagination for admin pages (domains, mailboxes, etc.)
* Code refactoring see #76
This commit is contained in:
@@ -17,3 +17,5 @@ parameters.register_admin("MAILDIR_ROOT", type="string", deflt=".maildir",
|
||||
parameters.register_admin("PASSWORD_SCHEME", type="list", deflt="crypt",
|
||||
values=[("crypt", "crypt"), ("md5", "md5"), ("clear", "clear")],
|
||||
help=_("Scheme used to crypt mailbox passwords"))
|
||||
parameters.register_admin("ITEMS_PER_PAGE", type="int", deflt=30,
|
||||
help=_("Number of displayed items per page"))
|
||||
|
||||
@@ -62,6 +62,15 @@ class DatesAware(models.Model):
|
||||
ObjectDates.set_for_object(self)
|
||||
super(DatesAware, self).save(*args, **kwargs)
|
||||
|
||||
def __creation(self):
|
||||
return self.dates.creation
|
||||
|
||||
def __last_modification(self):
|
||||
return self.dates.last_modification
|
||||
|
||||
creation = property(__creation)
|
||||
last_modification = property(__last_modification)
|
||||
|
||||
class Domain(DatesAware):
|
||||
name = models.CharField(_('name'), max_length=100, unique=True,
|
||||
help_text=_("The domain name"))
|
||||
@@ -157,6 +166,11 @@ class Mailbox(DatesAware):
|
||||
|
||||
full_address = property(__full_address)
|
||||
|
||||
def __enabled(self):
|
||||
return self.user.is_active
|
||||
|
||||
enabled = property(__enabled)
|
||||
|
||||
def create_dir(self):
|
||||
relpath = "%s/%s" % (self.domain.name, self.address)
|
||||
abspath = os.path.join(parameters.get_admin("STORAGE_PATH"), relpath)
|
||||
@@ -273,6 +287,16 @@ class Alias(DatesAware):
|
||||
("view_aliases", "View aliases"),
|
||||
)
|
||||
|
||||
def __full_address(self):
|
||||
return "%s@%s" % (self.address, self.domain.name)
|
||||
full_address = property(__full_address)
|
||||
|
||||
def __targets(self):
|
||||
ret = "<br/>".join(map(lambda m: str(m), self.mboxes.all()))
|
||||
ret += "<br/>" + self.repr_extmboxes()
|
||||
return ret
|
||||
targets = property(__targets)
|
||||
|
||||
def save(self, int_targets, ext_targets, *args, **kwargs):
|
||||
if len(ext_targets):
|
||||
self.extmboxes = ",".join(ext_targets)
|
||||
@@ -320,6 +344,15 @@ class Alias(DatesAware):
|
||||
"""
|
||||
return "<br/>".join(self.extmboxes.split(","))
|
||||
|
||||
def ui_disabled(self, user):
|
||||
if user.is_superuser:
|
||||
return False
|
||||
usermb = Mailbox.objects.get(user=user.id)
|
||||
for mb in self.mboxes.all():
|
||||
if mb.domain.id != usermb.domain.id:
|
||||
return True
|
||||
return False
|
||||
|
||||
class Extension(models.Model):
|
||||
name = models.CharField(max_length=150)
|
||||
enabled = models.BooleanField(_('enabled'),
|
||||
|
||||
@@ -73,7 +73,7 @@ class SuperAdminsPerms(Permissions):
|
||||
"full_name" : "%s %s" % (admin.first_name, admin.last_name),
|
||||
"date_joined" : admin.date_joined,
|
||||
"enabled" : admin.is_active}]
|
||||
return SuperAdminsTable(admins_list).render(request)
|
||||
return SuperAdminsTable(request, admins_list).render()
|
||||
|
||||
|
||||
class DomainAdminsPerms(Permissions):
|
||||
@@ -123,7 +123,7 @@ class DomainAdminsPerms(Permissions):
|
||||
domadmins_list = []
|
||||
for admin in domadmins:
|
||||
domadmins_list += [admin.tohash()]
|
||||
return DomainAdminsTable(domadmins_list).render(request)
|
||||
return DomainAdminsTable(request, domadmins_list).render()
|
||||
|
||||
def get_perms_class(user, role):
|
||||
"""Retrieves the class associated to a given role
|
||||
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
# coding: utf-8
|
||||
from django.utils.translation import ugettext as _
|
||||
from modoboa.lib import tables
|
||||
from templatetags.admin_extras import *
|
||||
|
||||
class DomsTable(tables.Table):
|
||||
tableid = "objects_table"
|
||||
idkey = "id"
|
||||
|
||||
name = tables.Column("name", label=_("Name"))
|
||||
creation = tables.Column("creation", label=_("Created"), width="160px")
|
||||
modified = tables.Column("last_modification", label=_("Last modified"),
|
||||
width="160px")
|
||||
domaliases = tables.Column("domainalias_set", label=_("Domain aliases"),
|
||||
width="100px", align="center")
|
||||
mboxes = tables.Column("mailbox_set", label=_("Mailboxes"),
|
||||
width="100px", align="center")
|
||||
mbaliases = tables.Column("mbalias_counter", label=_("Mailbox aliases"),
|
||||
width="100px", align="center")
|
||||
quota = tables.Column("quota", label=_("Quota"), width="50px", align="center")
|
||||
enabled = tables.Column("enabled", label=_("Enabled"), width="50px",
|
||||
align="center")
|
||||
actions = tables.ActionColumn("actions", label=_("Actions"), width="50px",
|
||||
align="center", defvalue=domain_actions)
|
||||
|
||||
cols_order = ["name", "creation", "modified",
|
||||
"domaliases", "mboxes", "mbaliases",
|
||||
"quota", "enabled", "actions"]
|
||||
|
||||
def __init__(self, request, doms):
|
||||
super(DomsTable, self).__init__(request)
|
||||
self.populate(self._rows_from_model(doms))
|
||||
|
||||
def parse_domainalias_set(self, value):
|
||||
return len(value.all())
|
||||
|
||||
def parse_mailbox_set(self, value):
|
||||
return len(value.all())
|
||||
|
||||
def parse_quota(self, value):
|
||||
return "%s %s" % (value, _("MB"))
|
||||
|
||||
def parse_enabled(self, value):
|
||||
return _("yes") if value else _("no")
|
||||
|
||||
class DomAliasesTable(tables.Table):
|
||||
tableid = "objects_table"
|
||||
idkey = "id"
|
||||
|
||||
name = tables.Column("name", label=_("Name"))
|
||||
target = tables.Column("target", label=_("Targeted domain"))
|
||||
creation = tables.Column("creation", label=_("Created"), width="170px")
|
||||
modified = tables.Column("last_modification", label=_("Last modified"),
|
||||
width="170px")
|
||||
enabled = tables.Column("enabled", label=_("Enabled"), width="50px",
|
||||
align="center")
|
||||
actions = tables.ActionColumn("actions", label=_("Actions"), width="50px",
|
||||
align="center", defvalue=domalias_actions)
|
||||
|
||||
cols_order = ["name", "target", "creation",
|
||||
"modified", "enabled", "actions"]
|
||||
|
||||
def __init__(self, request, domaliases):
|
||||
super(DomAliasesTable, self).__init__(request)
|
||||
self.populate(self._rows_from_model(domaliases))
|
||||
|
||||
def parse_enabled(self, value):
|
||||
return _("yes") if value else _("no")
|
||||
|
||||
class MailboxesTable(tables.Table):
|
||||
tableid = "objects_table"
|
||||
idkey = "id"
|
||||
|
||||
address = tables.Column("address", label=_("Address"))
|
||||
name = tables.Column("name", label=_("Name"))
|
||||
creation = tables.Column("creation", label=_("Created"), width="160px")
|
||||
modified = tables.Column("last_modification", label=_("Last modified"),
|
||||
width="160px")
|
||||
aliases = tables.Column("alias_set", label=_("Aliases"), width="70px",
|
||||
align="center")
|
||||
quota = tables.Column("quota", label=_("Quota"), width="50px", align="center")
|
||||
enabled = tables.Column("enabled", label=gender("Enabled", "f"), width="50px",
|
||||
align="center")
|
||||
actions = tables.ActionColumn("actions", label=_("Actions"), width="70px",
|
||||
align="center", defvalue=mailbox_actions)
|
||||
|
||||
cols_order = ["address", "name", "creation", "modified", "aliases",
|
||||
"quota", "enabled", "actions"]
|
||||
|
||||
def __init__(self, request, mailboxes):
|
||||
super(MailboxesTable, self).__init__(request)
|
||||
self.populate(self._rows_from_model(mailboxes))
|
||||
|
||||
def parse_alias_set(self, value):
|
||||
return len(value.all())
|
||||
|
||||
def parse_quota(self, value):
|
||||
return "%s %s" % (value, _("MB"))
|
||||
|
||||
def parse_enabled(self, value):
|
||||
return _("yes") if value else _("no")
|
||||
|
||||
class MbAliasesTable(tables.Table):
|
||||
tableid = "objects_table"
|
||||
idkey = "id"
|
||||
|
||||
address = tables.Column("full_address", label=_("Address"))
|
||||
targets = tables.Column("targets", label=_("Target(s)"), safe=True)
|
||||
creation = tables.Column("creation", label=_("Created"), width="170px")
|
||||
modified = tables.Column("last_modification", label=_("Last modified"),
|
||||
width="170px")
|
||||
enabled = tables.Column("enabled", label=gender("Enabled", "m"), width="50px",
|
||||
align="center")
|
||||
actions = tables.ActionColumn("actions", label=_("Actions"), width="50px",
|
||||
align="center", defvalue=mbalias_actions)
|
||||
|
||||
cols_order = ["address", "targets", "creation", "modified", "enabled", "actions"]
|
||||
|
||||
def __init__(self, request, aliases):
|
||||
super(MbAliasesTable, self).__init__(request)
|
||||
self.populate(self._rows_from_model(aliases))
|
||||
|
||||
def rowoptions(self, request, alias):
|
||||
return "{ui_disabled : '%s'}" % alias.ui_disabled(request.user)
|
||||
|
||||
def parse_enabled(self, value):
|
||||
return _("yes") if value else _("no")
|
||||
|
||||
|
||||
|
||||
@@ -170,26 +170,31 @@ def domalias_actions(user, aid):
|
||||
return render_actions(actions)
|
||||
|
||||
@register.simple_tag
|
||||
def mailbox_actions(user, mbox):
|
||||
def mailbox_actions(user, mboxid):
|
||||
actions = [
|
||||
{"name" : "editmailbox",
|
||||
"url" : reverse(admin.views.editmailbox, args=[mbox.id]),
|
||||
"url" : reverse(admin.views.editmailbox, args=[mboxid]),
|
||||
"img" : static_url("pics/edit.png"),
|
||||
"title" : _("Edit mailbox"),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:300,y:320}}"},
|
||||
{"name" : "aliases",
|
||||
"url" : reverse(admin.views.mbaliases) + "?mbid=%d" % mbox.id,
|
||||
"url" : reverse(admin.views.mbaliases) + "?mbid=%d" % mboxid,
|
||||
"img" : static_url("pics/alias.png"),
|
||||
"title" : _("View this mailbox aliases")},
|
||||
]
|
||||
return render_actions(actions)
|
||||
|
||||
@register.simple_tag
|
||||
def mbalias_actions(user, alias):
|
||||
def mbalias_actions(user, aliasid):
|
||||
from admin.models import Alias
|
||||
|
||||
alias = Alias.objects.get(pk=aliasid)
|
||||
if alias.ui_disabled(user):
|
||||
return "--"
|
||||
actions = [
|
||||
{"name" : "editmbalias",
|
||||
"url" : reverse(admin.views.editmbalias, args=[alias.id]),
|
||||
"url" : reverse(admin.views.editmbalias, args=[aliasid]),
|
||||
"img" : static_url("pics/edit.png"),
|
||||
"title" : _("Edit mailbox alias"),
|
||||
"class" : "boxed",
|
||||
|
||||
+49
-24
@@ -10,11 +10,13 @@ from django.db.models import Q
|
||||
from django.contrib.auth.models import User, Group
|
||||
from django.contrib import messages
|
||||
from django.db import transaction, IntegrityError
|
||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||
|
||||
from lib import *
|
||||
from modoboa import admin, userprefs
|
||||
from models import *
|
||||
from admin.permissions import *
|
||||
from admin.tables import *
|
||||
from modoboa.lib import crypt_password
|
||||
from modoboa.lib import _render, ajax_response, ajax_simple_response, \
|
||||
getctx, events, parameters
|
||||
@@ -22,14 +24,28 @@ from modoboa.lib.emailutils import split_mailbox
|
||||
from modoboa.lib.models import Parameter
|
||||
import copy
|
||||
|
||||
def render_domains_page(request, page, **kwargs):
|
||||
template = "admin/%s.html" % page
|
||||
def render_domains_page(request, objtype, tblclass, tplname="admin/listing.html",
|
||||
**kwargs):
|
||||
if request.GET.has_key("domid"):
|
||||
kwargs["domid"] = request.GET["domid"]
|
||||
else:
|
||||
kwargs["domid"] = ""
|
||||
kwargs["selection"] = page
|
||||
return _render(request, template, kwargs)
|
||||
kwargs["selection"] = objtype
|
||||
paginator = Paginator(kwargs["objects"],
|
||||
int(parameters.get_admin("ITEMS_PER_PAGE")))
|
||||
try:
|
||||
page = request.GET.get("page", "1")
|
||||
except ValueError:
|
||||
page = 1
|
||||
try:
|
||||
kwargs["objects"] = paginator.page(page)
|
||||
except (EmptyPage, PageNotAnInteger):
|
||||
kwargs["objects"] = paginator.page(paginator.num_pages)
|
||||
kwargs["last_page"] = paginator.num_pages
|
||||
kwargs["total"] = paginator.count
|
||||
kwargs["table"] = tblclass(request, kwargs["objects"].object_list).render()
|
||||
|
||||
return _render(request, tplname, kwargs)
|
||||
|
||||
@login_required
|
||||
def domains(request):
|
||||
@@ -43,8 +59,12 @@ def domains(request):
|
||||
for dom in domains:
|
||||
dom.mbalias_counter = len(Alias.objects.filter(domain=dom.id))
|
||||
deloptions = {"keepdir" : _("Do not delete domain directory")}
|
||||
return render_domains_page(request, "domains",
|
||||
domains=domains,
|
||||
return render_domains_page(request, "domains", DomsTable,
|
||||
"admin/domains.html",
|
||||
title=_("Available domains"),
|
||||
emptymsg=_("No domain defined."),
|
||||
objects=domains,
|
||||
rel="310 190",
|
||||
deloptions=deloptions)
|
||||
|
||||
def _validate_domain(request, form, successmsg, commonctx,
|
||||
@@ -137,8 +157,11 @@ def domaliases(request):
|
||||
else:
|
||||
domain = None
|
||||
domaliases = DomainAlias.objects.all()
|
||||
return render_domains_page(request, "domaliases",
|
||||
domaliases=domaliases, domain=domain)
|
||||
return render_domains_page(request, "domaliases", DomAliasesTable,
|
||||
title=_("Domain aliases"),
|
||||
emptymsg=_("No domain alias defined."),
|
||||
rel="310 190",
|
||||
objects=domaliases)
|
||||
|
||||
@login_required
|
||||
@good_domain
|
||||
@@ -227,8 +250,11 @@ def mailboxes(request):
|
||||
mboxes = Mailbox.objects.all()
|
||||
domain = None
|
||||
deloptions = {"keepdir" : _("Do not delete mailbox directory")}
|
||||
return render_domains_page(request, "mailboxes",
|
||||
mailboxes=mboxes, domain=domain, deloptions=deloptions)
|
||||
return render_domains_page(request, "mailboxes", MailboxesTable,
|
||||
title=_("Available mailboxes"),
|
||||
emptymsg=_("No mailbox defined."),
|
||||
rel="310 320",
|
||||
objects=mboxes, domain=domain, deloptions=deloptions)
|
||||
|
||||
@login_required
|
||||
@good_domain
|
||||
@@ -360,15 +386,12 @@ def mbaliases(request):
|
||||
aliases = Alias.objects.filter(mboxes__id=request.GET["mbid"]).distinct()
|
||||
else:
|
||||
aliases = Alias.objects.all()
|
||||
if not request.user.is_superuser:
|
||||
usermb = Mailbox.objects.get(user=request.user.id)
|
||||
for al in aliases:
|
||||
al.ui_disabled = False
|
||||
for mb in al.mboxes.all():
|
||||
if mb.domain.id != usermb.domain.id:
|
||||
al.ui_disabled = True
|
||||
break
|
||||
return render_domains_page(request, "mbaliases", aliases=aliases)
|
||||
|
||||
return render_domains_page(request, "mbaliases", MbAliasesTable,
|
||||
title=_("Mailbox aliases"),
|
||||
emptymsg=_("No mailbox alias defined."),
|
||||
rel="320 300",
|
||||
objects=aliases)
|
||||
|
||||
def _validate_mbalias(request, form, successmsg, tplname, commonctx):
|
||||
"""Mailbox alias validation
|
||||
@@ -546,9 +569,11 @@ def viewextensions(request, tplname='admin/extensions.html'):
|
||||
class ExtensionsTable(tables.Table):
|
||||
idkey = "id"
|
||||
selection = tables.SelectionColumn("selection", width="4%", first=True)
|
||||
_1_name = tables.Column("name", label=_("Name"), width="15%")
|
||||
_2_version = tables.Column("version", label=_("Version"), width="6%")
|
||||
_3_descr = tables.Column("description", label=_("Description"))
|
||||
name = tables.Column("name", label=_("Name"), width="15%")
|
||||
version = tables.Column("version", label=_("Version"), width="6%")
|
||||
descr = tables.Column("description", label=_("Description"))
|
||||
|
||||
cols_order = ["selection", "name", "version", "descr"]
|
||||
|
||||
exts = list_extensions()
|
||||
for ext in exts:
|
||||
@@ -562,9 +587,9 @@ def viewextensions(request, tplname='admin/extensions.html'):
|
||||
dbext.save()
|
||||
ext["selection"] = False
|
||||
|
||||
tbl = ExtensionsTable(exts)
|
||||
tbl = ExtensionsTable(request, exts)
|
||||
return _render(request, tplname, {
|
||||
"extensions" : tbl.render(request)
|
||||
"extensions" : tbl.render()
|
||||
})
|
||||
|
||||
@login_required
|
||||
|
||||
@@ -2,29 +2,27 @@
|
||||
|
||||
from datetime import datetime
|
||||
from django.utils.translation import ugettext as _
|
||||
from modoboa.lib import tables, db
|
||||
from modoboa.lib import tables, db, static_url
|
||||
from modoboa.lib.email_listing import MBconnector, EmailListing
|
||||
from modoboa.lib.emailutils import *
|
||||
|
||||
class Qtable(tables.Table):
|
||||
tableid = "emails"
|
||||
idkey = "mailid"
|
||||
#selection = tables.SelectionColumn("selection", first=True)
|
||||
_1_type = tables.Column("type", align="center", width="30px",
|
||||
label="<input type='checkbox' name='toggleselect' id='toggleselect' />")
|
||||
_2_from_ = tables.Column("from", label=_("From"))
|
||||
_3_subject = tables.Column("subject", label=_("Subject"))
|
||||
_4_time = tables.Column("date", label=_("Date"))
|
||||
|
||||
type = tables.Column("type", align="center", width="30px",
|
||||
label="<input type='checkbox' name='toggleselect' id='toggleselect' />")
|
||||
rstatus = tables.ImgColumn("rstatus", width='25px')
|
||||
from_ = tables.Column("from", label=_("From"), limit=30)
|
||||
subject = tables.Column("subject", label=_("Subject"), limit=40)
|
||||
time = tables.Column("date", label=_("Date"))
|
||||
to = tables.Column("to", label=_("To"), limit=30)
|
||||
|
||||
cols_order = ['type', 'rstatus', 'to', 'from_', 'subject', 'time']
|
||||
|
||||
def parse_date(self, value):
|
||||
return datetime.fromtimestamp(value)
|
||||
|
||||
def parse(self, header, value):
|
||||
try:
|
||||
return getattr(self, "parse_%s" % header)(value)
|
||||
except AttributeError:
|
||||
return value
|
||||
|
||||
class SQLconnector(MBconnector):
|
||||
def __init__(self, filter=None):
|
||||
self.conn = db.getconnection("amavis_quarantine")
|
||||
@@ -77,10 +75,13 @@ LIMIT %d,%d
|
||||
emails = []
|
||||
rows = cursor.fetchall()
|
||||
for row in rows:
|
||||
emails.append({"from" : row[0], "to" : row[1],
|
||||
"subject" : row[2], "content" : row[3],
|
||||
"mailid" : row[4], "date" : row[5],
|
||||
"type" : row[6]})
|
||||
m = {"from" : row[0], "to" : row[1],
|
||||
"subject" : row[2], "content" : row[3],
|
||||
"mailid" : row[4], "date" : row[5],
|
||||
"type" : row[6]}
|
||||
if row[7] == "R":
|
||||
m["img_rstatus"] = static_url("pics/release.png");
|
||||
emails.append(m)
|
||||
return emails
|
||||
|
||||
class SQLlisting(EmailListing):
|
||||
@@ -90,7 +91,9 @@ class SQLlisting(EmailListing):
|
||||
defcallback = "updatelisting"
|
||||
reset_wm_url = True
|
||||
|
||||
def __init__(self, filter, **kwargs):
|
||||
def __init__(self, user, filter, **kwargs):
|
||||
if not user.is_superuser:
|
||||
Qtable.cols_order.remove('to')
|
||||
self.mbc = SQLconnector(filter)
|
||||
EmailListing.__init__(self, **kwargs)
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ def _listing(request, internal=False, filter=None):
|
||||
|
||||
pageid = request.GET.has_key("page") and int(request.GET["page"]) or 1
|
||||
request.session["page"] = pageid # ?? nécessaire
|
||||
lst = SQLlisting(filter, baseurl="listing/", empty=internal,
|
||||
lst = SQLlisting(request.user, filter, baseurl="listing/", empty=internal,
|
||||
elems_per_page=int(parameters.get_user(request.user,
|
||||
"MESSAGES_PER_PAGE")))
|
||||
if internal:
|
||||
@@ -165,6 +165,7 @@ WHERE msgrcpt.mail_id=msgs.mail_id AND msgrcpt.rid=maddr.id AND msgs.mail_id IN
|
||||
result = amr.sendreq(k, values["secret"], *values["rcpts"])
|
||||
if result:
|
||||
count += 1
|
||||
db.execute(conn, "UPDATE msgrcpt SET rs='R' WHERE mail_id='%s'" % k)
|
||||
else:
|
||||
error = result
|
||||
break
|
||||
|
||||
@@ -119,12 +119,6 @@ textarea:hover {
|
||||
}
|
||||
|
||||
/* Progress bar */
|
||||
#footer {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
#quotalabel {
|
||||
float: left;
|
||||
padding: 7px 2px 0 5px;
|
||||
|
||||
@@ -107,14 +107,15 @@ class EmailListing:
|
||||
return render_to_string("common/navbar.html", context)
|
||||
|
||||
def fetch(self, request, id_start, id_stop):
|
||||
table = self.tbltype(self.mbc.fetch(start=id_start, stop=id_stop,
|
||||
table = self.tbltype(request,
|
||||
self.mbc.fetch(start=id_start, stop=id_stop,
|
||||
folder=self.folder,
|
||||
nbelems=self.elems_per_page))
|
||||
tpl = Template("""
|
||||
<form method="POST" id="listingform">
|
||||
{{ table }}
|
||||
</form>""")
|
||||
return tpl.render(Context({"table" : table.render(request)}))
|
||||
return tpl.render(Context({"table" : table.render()}))
|
||||
|
||||
def render(self, request, pageid=1, **kwargs):
|
||||
listing = ""
|
||||
|
||||
+71
-7
@@ -48,22 +48,46 @@ class DivColumn(Column):
|
||||
def render(self):
|
||||
return "<div> </div>"
|
||||
|
||||
class ActionColumn(Column):
|
||||
def render(self, fct, user, rowid):
|
||||
return fct(user, rowid)
|
||||
|
||||
class Table(object):
|
||||
tableid = ""
|
||||
|
||||
def __init__(self, rows={}):
|
||||
def __init__(self, request, rows={}):
|
||||
self.columns = []
|
||||
for m in inspect.getmembers(self):
|
||||
if isinstance(m[1], Column):
|
||||
self.request = request
|
||||
try:
|
||||
order = getattr(self, "cols_order")
|
||||
except AttributeError:
|
||||
for m in inspect.getmembers(self):
|
||||
if isinstance(m[1], Column):
|
||||
try:
|
||||
if getattr(m[1], "first"):
|
||||
self.columns = [m[1]] + self.columns
|
||||
except AttributeError:
|
||||
self.columns += [m[1]]
|
||||
else:
|
||||
for colname in order:
|
||||
try:
|
||||
if getattr(m[1], "first"):
|
||||
self.columns = [m[1]] + self.columns
|
||||
col = getattr(self, colname)
|
||||
except AttributeError:
|
||||
self.columns += [m[1]]
|
||||
continue
|
||||
if not isinstance(col, Column):
|
||||
continue
|
||||
self.columns += [col]
|
||||
|
||||
if rows != {}:
|
||||
self.populate(rows)
|
||||
|
||||
def populate(self, rows):
|
||||
self.rows = []
|
||||
trcpt = 0
|
||||
for row in rows:
|
||||
nrow = {"id" : row[self.idkey], "cols" : [], "trcpt" : trcpt}
|
||||
if row.has_key("options"):
|
||||
nrow["options"] = row["options"]
|
||||
for c in self.columns:
|
||||
newcol = {"name" : c.name}
|
||||
for key in ["width", "align", "cssclass"]:
|
||||
@@ -88,6 +112,9 @@ class Table(object):
|
||||
elif isinstance(c, DivColumn):
|
||||
newcol["value"] = c.render()
|
||||
newcol["safe"] = True
|
||||
elif isinstance(c, ActionColumn):
|
||||
newcol["value"] = c.render(c.defvalue, self.request.user, nrow["id"])
|
||||
newcol["safe"] = True
|
||||
elif row.has_key(c.name):
|
||||
if "class" in row.keys():
|
||||
newcol["cssclass"] += newcol["cssclass"] != "" \
|
||||
@@ -96,11 +123,48 @@ class Table(object):
|
||||
newcol["value"] = self.parse(c.name, row[c.name])
|
||||
except AttributeError:
|
||||
newcol["value"] = row[c.name]
|
||||
try:
|
||||
limit = getattr(c, "limit")
|
||||
if len(newcol["value"]) > limit:
|
||||
newcol["value"] = newcol["value"][0:limit] + "..."
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
newcol["safe"] = getattr(c, "safe")
|
||||
except AttributeError:
|
||||
pass
|
||||
nrow["cols"] += [newcol]
|
||||
self.rows += [nrow]
|
||||
trcpt += 1
|
||||
|
||||
def _rows_from_model(self, objects):
|
||||
rows = []
|
||||
for obj in objects:
|
||||
nrow = {}
|
||||
try:
|
||||
idkey = getattr(self, "idkey")
|
||||
nrow[idkey] = getattr(obj, idkey)
|
||||
except AttributeError:
|
||||
pass
|
||||
for c in self.columns:
|
||||
try:
|
||||
nrow[c.name] = getattr(obj, c.name)
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
nrow["options"] = getattr(self, "rowoptions")(self.request, obj)
|
||||
except AttributeError:
|
||||
pass
|
||||
rows += [nrow]
|
||||
return rows
|
||||
|
||||
def render(self, request):
|
||||
def parse(self, header, value):
|
||||
try:
|
||||
return getattr(self, "parse_%s" % header)(value)
|
||||
except AttributeError:
|
||||
return value
|
||||
|
||||
def render(self):
|
||||
if len(self.rows):
|
||||
t = Template("""
|
||||
<table id="{{ tableid }}">
|
||||
|
||||
@@ -34,6 +34,27 @@ div#footer {
|
||||
height: 30px;
|
||||
bottom: 0px;
|
||||
border-top: 5px solid #333;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
#navbar {
|
||||
float: right;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#navbar label {
|
||||
color: white;
|
||||
margin-right: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#navbar img {
|
||||
margin-top: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#menubar {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% extends "admin/domains_header.html" %}
|
||||
{% extends "admin/listing.html" %}
|
||||
{% load i18n admin_extras libextras %}
|
||||
{% block html_head %}
|
||||
{{ block.super }}
|
||||
@@ -9,37 +9,3 @@
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block middletitle %}{% trans "Available domains" %}{% endblock %}
|
||||
{% block subcontent %}
|
||||
<div id="objects" name="domains" rel="310 190">
|
||||
{% if not domains %}<div class="info">{% trans "No domain defined." %}</div>
|
||||
{% else %}
|
||||
<table id="objects_table">
|
||||
<tr>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th width="160px">{% trans "Created" %}</th>
|
||||
<th width="160px">{% trans "Last modified" %}</th>
|
||||
<th width="100px" class="center">{% trans "Domain aliases" %}</th>
|
||||
<th width="100px" class="center">{% trans "Mailboxes" %}</th>
|
||||
<th width="100px" class="center">{% trans "Mailbox aliases" %}</th>
|
||||
<th width="50px" class="center">{% trans "Quota" %}</th>
|
||||
<th width="50px" class="center">{% trans "Enabled" %}</th>
|
||||
<th width="50px" class="center">{% trans "Actions" %}</th>
|
||||
</tr>
|
||||
{% for dom in domains %}
|
||||
<tr class="{% cycle 'odd' 'even' %}" id="{{ dom.id }}">
|
||||
<td>{{ dom.name }}</td>
|
||||
<td>{{ dom.dates.creation }}</td>
|
||||
<td>{{ dom.dates.last_modification }}</td>
|
||||
<td class="center">{{ dom.domainalias_set.all|length }}</td>
|
||||
<td class="center">{{ dom.mailbox_set.all|length }}</td>
|
||||
<td class="center">{{ dom.mbalias_counter }}</td>
|
||||
<td class="center">{{ dom.quota }} {% trans "MB" %}</td>
|
||||
<td class="center">{{ dom.enabled|yesno:_("yes,no") }}</td>
|
||||
<td class="center">{% domain_actions user dom.id %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
{% extends "admin/domains_header.html" %}
|
||||
{% load i18n admin_extras libextras %}
|
||||
{% block pagetitle %}{% trans "Domain aliases" %}{% endblock %}
|
||||
{% block subcontent %}
|
||||
<div id="objects" name="domaliases" rel="310 190">
|
||||
{% if not domaliases %}
|
||||
<div class="info">{% trans "No domain alias defined." %}</div>
|
||||
{% else %}
|
||||
<table id="objects_table">
|
||||
<tr>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th>{% trans "Targeted domain" %}</th>
|
||||
<th width="170px">{% trans "Created" %}</th>
|
||||
<th width="170px">{% trans "Last modified" %}</th>
|
||||
<th width="50px" class="center">{% trans "Enabled" %}</th>
|
||||
<th width="50px" class="center">{% trans "Actions" %}</th>
|
||||
</tr>
|
||||
{% for domalias in domaliases %}
|
||||
<tr class="{% cycle 'odd' 'even' %}" id="{{ domalias.id }}">
|
||||
<td>{{ domalias.name }}</td>
|
||||
<td>{{ domalias.target.name }}</td>
|
||||
<td>{{ domalias.dates.creation }}</td>
|
||||
<td>{{ domalias.dates.last_modification }}</td>
|
||||
<td class="center">{{ domalias.enabled|yesno }}</td>
|
||||
<td class="center">{% domalias_actions user domalias.id %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,34 @@
|
||||
{% extends "admin/domains_header.html" %}
|
||||
{% load i18n %}
|
||||
{% block middletitle %}{{ title }}{% endblock %}
|
||||
{% block subcontent %}
|
||||
<div id="objects" name="{{ selection }}" rel="{{ rel }}">
|
||||
{% if not objects %}<div class="info">{{ emptymsg }}</div>
|
||||
{% else %}
|
||||
{{ table }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block footer %}
|
||||
<div id="navbar">
|
||||
{% if total %}
|
||||
<label>{% trans "Items" %} {{ objects.start_index }} {% trans "to" %} {{ objects.end_index }} {% trans "of" %} {{ total }}</label>
|
||||
{% endif %}
|
||||
{% if objects.has_previous %}
|
||||
<a href="?page=1">
|
||||
<img src="{{ MEDIA_URL }}pics/first.png" border="0" title="{% trans "First" %}" />
|
||||
</a>
|
||||
<a href="?page={{ objects.previous_page_number }}">
|
||||
<img src="{{ MEDIA_URL }}pics/back.png" border="0" title="{% trans "Previous" %}" />
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if objects.has_next %}
|
||||
<a href="?page={{ objects.next_page_number }}">
|
||||
<img src="{{ MEDIA_URL }}pics/next.png" border="0" title="{% trans "Next" %}" />
|
||||
</a>
|
||||
<a href="?page={{ page.last_page }}">
|
||||
<img src="{{ MEDIA_URL }}pics/last.png" border="0" title="{% trans "Last" %}" />
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,35 +0,0 @@
|
||||
{% extends "admin/domains_header.html" %}
|
||||
{% load i18n admin_extras %}
|
||||
{% block pagetitle %}{% trans "Available mailboxes" %}{% endblock %}
|
||||
{% block subcontent %}
|
||||
<div id="objects" name="mailboxes" rel="310 320">
|
||||
{% if not mailboxes %}
|
||||
<div class="info">{% trans "No mailbox defined." %}</div>
|
||||
{% else %}
|
||||
<table id="objects_table">
|
||||
<tr>
|
||||
<th>{% trans "Address" %}</th>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th width="160px">{% trans "Created" %}</th>
|
||||
<th width="160px">{% trans "Last modified" %}</th>
|
||||
<th width="70px" class="center">{% trans "Aliases" %}</th>
|
||||
<th width="50px" class="center">{% trans "Quota" %}</th>
|
||||
<th width="50px" class="center">{{ "Enabled"|gender:"f" }}</th>
|
||||
<th width="70px" class="center">{% trans "Actions" %}</th>
|
||||
</tr>
|
||||
{% for mb in mailboxes %}
|
||||
<tr class="{% cycle 'odd' 'even' %}" id="{{ mb.id }}">
|
||||
<td>{{ mb.full_address }}</td>
|
||||
<td>{{ mb.name }}</td>
|
||||
<td>{{ mb.dates.creation }}</td>
|
||||
<td>{{ mb.dates.last_modification }}</td>
|
||||
<td class="center">{{ mb.alias_set.all|length }}</td>
|
||||
<td class="center">{{ mb.quota }} {% trans "MB" %}</td>
|
||||
<td class="center">{{ mb.user.is_active|yesno:_("yes,no") }}</td>
|
||||
<td class="center">{% mailbox_actions user mb %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,39 +0,0 @@
|
||||
{% extends "admin/domains_header.html" %}
|
||||
{% load i18n admin_extras %}
|
||||
{% block pagetitle %}{% trans "Mailbox aliases" %}{% endblock %}
|
||||
{% block subcontent %}
|
||||
<div id="objects" name="mbaliases" rel="320 300">
|
||||
{% if not aliases %}
|
||||
<div class="info">{% trans "No mailbox alias defined." %}</div>
|
||||
{% else %}
|
||||
<table id="objects_table">
|
||||
<tr>
|
||||
<th>{% trans "Address" %}</th>
|
||||
<th>{% trans "Target(s)" %}</th>
|
||||
<th width="170px">{% trans "Created" %}</th>
|
||||
<th width="170px">{% trans "Last modified" %}</th>
|
||||
<th width="50px" class="center">{% trans "Enabled" %}</th>
|
||||
<th width="50px" class="center">{% trans "Actions" %}</th>
|
||||
</tr>
|
||||
{% for alias in aliases %}
|
||||
<tr class="{% cycle 'odd' 'even' %}" id="{{ alias.id }}"
|
||||
rel="{ui_disabled : '{{ alias.ui_disabled }}'}">
|
||||
<td>{{ alias.address }}@{{ alias.domain }}</td>
|
||||
<td>
|
||||
{% for mb in alias.mboxes.all %}
|
||||
{{ mb.full_address }}<br/>
|
||||
{% endfor %}
|
||||
{{ alias.repr_extmboxes|safe }}
|
||||
</td>
|
||||
<td>{{ alias.dates.creation }}</td>
|
||||
<td>{{ alias.dates.last_modification }}</td>
|
||||
<td class="center">{{ alias.enabled|yesno }}</td>
|
||||
<td class="center">
|
||||
{% if alias.ui_disabled %}--{% else %}{% mbalias_actions user alias %}{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -7,26 +7,6 @@
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/ProgressBar.js"></script>
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}js/email_listing.js"></script>
|
||||
{% block css %}{% endblock %}
|
||||
<style type="text/css">
|
||||
#navbar {
|
||||
float: right;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#navbar label {
|
||||
color: white;
|
||||
margin-right: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#navbar img{
|
||||
margin-top: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
var current_anchor = new AnchorNavigation("{{ deflocation }}");
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<tbody>
|
||||
{% for row in table.rows %}
|
||||
<tr id="{{ row.id }}" class="{% cycle 'odd' 'even' %}" name="{{ row.trcpt }}">
|
||||
<tr id="{{ row.id }}" class="{% cycle 'odd' 'even' %}" name="{{ row.trcpt }}"
|
||||
rel="{{ row.options }}">
|
||||
{% for cell in row.cols %}
|
||||
<td name="{{ cell.name }}" width="{{ cell.width }}" align="{{ cell.align }}" class="{{ cell.cssclass }}">
|
||||
{% if cell.safe %}{{ cell.value|safe }}{% else %}{{ cell.value }}{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user