diff --git a/modoboa/admin/templates/admin/settings_header.html b/modoboa/admin/templates/admin/settings_header.html
index ad2c246ee..9be226e95 100644
--- a/modoboa/admin/templates/admin/settings_header.html
+++ b/modoboa/admin/templates/admin/settings_header.html
@@ -3,10 +3,15 @@
{% block pagetitle %}{% trans "Modoboa settings" %}{% endblock %}
{% block html_head %}
-
+
{% endblock %}
diff --git a/modoboa/admin/urls.py b/modoboa/admin/urls.py
index bede38e01..aea38672a 100644
--- a/modoboa/admin/urls.py
+++ b/modoboa/admin/urls.py
@@ -2,7 +2,7 @@ from django.conf.urls.defaults import *
urlpatterns = patterns(
'modoboa.admin.views',
- url(r'^$', 'domains', name="index"),
+ url(r'^$', 'index', name="index"),
url(r'^domains/$', 'domains', name="domains"),
(r'^domains/list/$', '_domains'),
(r'^domains/flatlist/$', 'domains_list'),
diff --git a/modoboa/admin/views.py b/modoboa/admin/views.py
index 01eb2ff95..28ea0ac8d 100644
--- a/modoboa/admin/views.py
+++ b/modoboa/admin/views.py
@@ -21,13 +21,12 @@ from modoboa.lib.models import Parameter
from modoboa.lib.permissions import *
@login_required
-def _domains(request):
- if not request.user.has_perm("admin.view_domains"):
- if request.user.has_perm("admin.view_mailboxes"):
- return HttpResponseRedirect(reverse(identities))
+def index(request):
+ return HttpResponseRedirect(reverse(domains))
- return HttpResponseRedirect(reverse("modoboa.userprefs.views.index"))
-
+@login_required
+@user_passes_test(lambda u: u.has_perm("admin.view_domains") or u.has_perm("admin.view_mailboxes"))
+def _domains(request):
domains = request.user.get_domains()
squery = request.GET.get("searchquery", None)
if squery is not None:
@@ -38,6 +37,12 @@ def _domains(request):
@login_required
def domains(request, tplname="admin/domains.html"):
+ if not request.user.has_perm("admin.view_domains"):
+ if request.user.has_perm("admin.view_mailboxes"):
+ return HttpResponseRedirect(reverse(identities))
+
+ return HttpResponseRedirect(reverse("modoboa.userprefs.views.index"))
+
return render(request, tplname, {
"selection" : "domains"
})
diff --git a/modoboa/extensions/__init__.py b/modoboa/extensions/__init__.py
index 1fb2e4910..37cdd3d95 100644
--- a/modoboa/extensions/__init__.py
+++ b/modoboa/extensions/__init__.py
@@ -64,9 +64,13 @@ class ExtensionsPool(object):
extinstance.load()
except Extension.DoesNotExist:
pass
- baseurl = extinstance.url if extinstance.url is not None else extname
- result += [(r'^%s/' % (baseurl),
- include("%s.urls" % extinstance.__module__))]
+ try:
+ baseurl = extinstance.url if extinstance.url is not None else extname
+ result += [(r'^%s/' % (baseurl),
+ include("%s.urls" % extinstance.__module__))]
+ except ImportError:
+ # No urls for this extension
+ pass
return result
def list_all(self):
diff --git a/modoboa/extensions/postfix_autoreply/__init__.py b/modoboa/extensions/postfix_autoreply/__init__.py
index 33d762cee..7846cf8a3 100644
--- a/modoboa/extensions/postfix_autoreply/__init__.py
+++ b/modoboa/extensions/postfix_autoreply/__init__.py
@@ -54,6 +54,17 @@ class PostfixAutoreply(ModoExtension):
exts_pool.register_extension(PostfixAutoreply)
+@events.observe("ExtraUprefsRoutes")
+def extra_routes():
+ return [(r'^autoreply/$', 'modoboa.extensions.postfix_autoreply.views.autoreply'),]
+
+@events.observe("ExtraUprefsJS")
+def extra_js():
+ return ["""function autoreply_cb() {
+ $('#id_untildate').datepicker({format: 'yyyy-mm-dd', language: '%s'});
+}
+""" % 'en']
+
@events.observe("UserMenuDisplay")
def menu(target, user):
import views
@@ -64,7 +75,8 @@ def menu(target, user):
return []
return [
{"name" : "autoreply",
- "url" : reverse(views.autoreply),
+ "class" : "ajaxlink",
+ "url" : "autoreply/",
"label" : ugettext_lazy("Auto-reply message")}
]
diff --git a/modoboa/extensions/postfix_autoreply/templates/postfix_autoreply/autoreply.html b/modoboa/extensions/postfix_autoreply/templates/postfix_autoreply/autoreply.html
index 4130eec0c..c5f30c794 100644
--- a/modoboa/extensions/postfix_autoreply/templates/postfix_autoreply/autoreply.html
+++ b/modoboa/extensions/postfix_autoreply/templates/postfix_autoreply/autoreply.html
@@ -1,20 +1,11 @@
-{% extends "userprefs/section.html" %}
-{% block html_head %}
-
-{% endblock %}
+{% load i18n libextras %}
+
{% trans "Auto-reply message" %} {% trans "Define a message to automatically send when you are off" %}
+
+
diff --git a/modoboa/extensions/postfix_autoreply/urls.py b/modoboa/extensions/postfix_autoreply/urls.py
deleted file mode 100644
index 4d71b3019..000000000
--- a/modoboa/extensions/postfix_autoreply/urls.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from django.conf.urls.defaults import *
-
-urlpatterns = patterns('modoboa.extensions.postfix_autoreply.views',
- url(r'^$', 'autoreply'),
- )
diff --git a/modoboa/extensions/postfix_autoreply/views.py b/modoboa/extensions/postfix_autoreply/views.py
index 24903dbc4..3e096c3aa 100644
--- a/modoboa/extensions/postfix_autoreply/views.py
+++ b/modoboa/extensions/postfix_autoreply/views.py
@@ -1,7 +1,7 @@
# coding: utf-8
from datetime import date
from django.http import HttpResponse
-from django.utils import simplejson
+from django.template.loader import render_to_string
from django.contrib.auth.decorators \
import login_required
from django.contrib import messages
@@ -14,7 +14,7 @@ from models import *
@login_required
@needs_mailbox()
-def autoreply(request, tplname="userprefs/section.html"):
+def autoreply(request, tplname="postfix_autoreply/autoreply.html"):
mb = Mailbox.objects.get(user=request.user.id)
try:
arm = ARmessage.objects.get(mbox=mb.id)
@@ -36,18 +36,19 @@ def autoreply(request, tplname="userprefs/section.html"):
status="ok", respmsg=_("Auto reply message updated successfully.")
))
- return ajax_response(request, status="ko", template="userprefs/form.html", form=form)
+ return ajax_simple_response({
+ "status" : "ko",
+ "content" : render_to_string(tplname, {"form" : form}),
+ "onload_cb" : "autoreply_cb"
+ })
- ctx = dict(
- title=_("Auto-reply message"),
- subtitle=_("Define a message to automatically send when you are off"),
- action=reverse(autoreply),
- left_selection="autoreply",
- )
form = ARmessageForm(instance=arm)
if arm is not None:
form.fields['untildate'].initial = arm.untildate
else:
form.fields['untildate'].initial = date.today()
- ctx.update(form=form)
- return _render(request, "postfix_autoreply/autoreply.html", ctx)
+ return ajax_simple_response({
+ "status" : "ok",
+ "content" : render_to_string(tplname, {"form" : form}),
+ "onload_cb" : "autoreply_cb"
+ })
diff --git a/modoboa/extensions/webmail/__init__.py b/modoboa/extensions/webmail/__init__.py
index c36d2066e..342fc2828 100644
--- a/modoboa/extensions/webmail/__init__.py
+++ b/modoboa/extensions/webmail/__init__.py
@@ -99,7 +99,7 @@ def userlogout(request):
m = IMAPconnector(user=request.user.username,
password=request.session["password"])
except Exception, e:
- pass
+ return
# The following statement may fail under Python 2.6...
try:
diff --git a/modoboa/lib/events.py b/modoboa/lib/events.py
index 6fb3245fa..51d82793d 100644
--- a/modoboa/lib/events.py
+++ b/modoboa/lib/events.py
@@ -59,6 +59,9 @@ events = [
"TopNotifications",
"ExtraAdminContent",
+
+ "ExtraUprefsRoutes",
+ "ExtraUprefsJS"
]
callbacks = {}
diff --git a/modoboa/static/js/global.js b/modoboa/static/js/global.js
index 771176d36..482b1e850 100644
--- a/modoboa/static/js/global.js
+++ b/modoboa/static/js/global.js
@@ -98,7 +98,7 @@ if (!Object.keys) {
function simple_ajax_form_post(e, options) {
e.preventDefault();
var $form = (options.formid != undefined) ? $("#" + options.formid) : $("form");
- var defaults = {reload_on_success: true, reload_mode: 'full'};
+ var defaults = {reload_on_success: true, reload_mode: 'full', modal: true};
var opts = $.extend({}, defaults, options);
var args = $form.serialize();
@@ -123,14 +123,16 @@ function simple_ajax_form_post(e, options) {
$("body").notify('success', data.respmsg, 2000);
}
} else {
- if (data.content != "") {
- $('.modal').html(data.content);
- }
- if (data.respmsg) {
- $('.modal-body').prepend(build_error_alert(data.respmsg));
+ if (opts.modal) {
+ if (data.content != "") {
+ $('.modal').html(data.content);
+ }
+ if (data.respmsg) {
+ $('.modal-body').prepend(build_error_alert(data.respmsg));
+ }
}
if (opts.error_cb != undefined) {
- opts.error_cb();
+ opts.error_cb(data);
}
}
});
diff --git a/modoboa/admin/static/admin/js/settings.js b/modoboa/static/js/twocols_nav.js
similarity index 53%
rename from modoboa/admin/static/admin/js/settings.js
rename to modoboa/static/js/twocols_nav.js
index bea2ee05d..64e17b1b2 100644
--- a/modoboa/admin/static/admin/js/settings.js
+++ b/modoboa/static/js/twocols_nav.js
@@ -1,19 +1,21 @@
-var Settings = function(options) {
+var TwocolsNav = function(options) {
this.initialize(options);
};
-Settings.prototype = {
- constructor: Settings,
+TwocolsNav.prototype = {
+ constructor: TwocolsNav,
defaults: {
- deflocation: "parameters/"
+ deflocation: null,
+ formid: "#form",
+ divid: "#content",
+ reload_exceptions: null
},
initialize: function(options) {
this.options = $.extend({}, this.defaults, options);
this.options.defcallback = $.proxy(this.default_cb, this);
this.navobj = new History(this.options);
-
this.listen();
},
@@ -21,16 +23,31 @@ Settings.prototype = {
$("a.ajaxlink").click($.proxy(this.load_page, this));
$(document).on("click", "#update", $.proxy(function(e) {
simple_ajax_form_post(e, {
- formid: "settings_form",
+ formid: this.options.formid,
+ modal: false,
reload_on_success: false,
+ error_cb: $.proxy(this.update_content, this),
success_cb: $.proxy(this.save_cb, this)
});
}, this));
},
+ update_content: function(data) {
+ $('#' + this.options.divid).html(data.content);
+ if (data.onload_cb) {
+ eval(data.onload_cb + '()');
+ }
+ $(".help").popover().click(function(e) {e.preventDefault();});
+ },
+
save_cb: function(data) {
- if (this.navobj.getbaseurl() == 'extensions') {
- window.location.reload();
+ if (this.options.reload_exceptions) {
+ for (var i = 0; i < this.options.reload_exceptions.length; i++) {
+ if (this.navobj.getbaseurl() == this.options.reload_exceptions[i]) {
+ window.location.reload();
+ break;
+ }
+ }
}
$("body").notify("success", data.respmsg, 2000);
},
@@ -44,6 +61,6 @@ Settings.prototype = {
default_cb: function(data) {
$("a.ajaxlink").parent().removeClass("active");
$("a[name=" + this.navobj.getbaseurl() + "]").parent().addClass("active");
- $("#settings_content").html(data.content);
+ this.update_content(data);
}
};
\ No newline at end of file
diff --git a/modoboa/userprefs/templates/userprefs/form.html b/modoboa/userprefs/templates/userprefs/form.html
deleted file mode 100644
index 53626c558..000000000
--- a/modoboa/userprefs/templates/userprefs/form.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% load i18n libextras %}
-{% render_form form %}
-
-
-
diff --git a/modoboa/userprefs/templates/userprefs/forward.html b/modoboa/userprefs/templates/userprefs/forward.html
new file mode 100644
index 000000000..5aaf2b009
--- /dev/null
+++ b/modoboa/userprefs/templates/userprefs/forward.html
@@ -0,0 +1,10 @@
+{% load i18n libextras %}
+{% trans "Forward" %} {% trans "Automatically forward emails to another address" %}
+
+
diff --git a/modoboa/userprefs/templates/userprefs/index.html b/modoboa/userprefs/templates/userprefs/index.html
new file mode 100644
index 000000000..9dee42e1c
--- /dev/null
+++ b/modoboa/userprefs/templates/userprefs/index.html
@@ -0,0 +1,19 @@
+{% extends "twocols.html" %}{% load i18n uprefs_extras libextras %}
+{% block pagetitle %}{% trans "Settings" %}{% endblock %}
+{% block html_head %}
+
+
+
+{% endblock %}
+{% block leftcol %}{% endblock %}
+{% block apparea %}{% endblock %}
diff --git a/modoboa/userprefs/templates/userprefs/preferences.html b/modoboa/userprefs/templates/userprefs/preferences.html
index 6e1767d99..f20af214c 100644
--- a/modoboa/userprefs/templates/userprefs/preferences.html
+++ b/modoboa/userprefs/templates/userprefs/preferences.html
@@ -1,30 +1,9 @@
-{% extends "twocols.html" %}{% load i18n uprefs_extras libextras %}
-{% block pagetitle %}{% trans "Settings" %}{% endblock %}
-{% block html_head %}
-
-{% endblock %}
-{% block leftcol %}{% endblock %}
-{% block apparea %}
- {% trans "Preferences" %} {% trans "Customize Modoboa" %}
+{% load i18n %}
+{% trans "Preferences" %} {% trans "Customize Modoboa" %}
+
+
-{% endblock %}
+
+
diff --git a/modoboa/userprefs/templates/userprefs/profile.html b/modoboa/userprefs/templates/userprefs/profile.html
new file mode 100644
index 000000000..709f93f37
--- /dev/null
+++ b/modoboa/userprefs/templates/userprefs/profile.html
@@ -0,0 +1,10 @@
+{% load i18n libextras %}
+{% trans "Profile" %} {% trans "Update your personal information" %}
+
+
diff --git a/modoboa/userprefs/templates/userprefs/section.html b/modoboa/userprefs/templates/userprefs/section.html
deleted file mode 100644
index d46aac5d2..000000000
--- a/modoboa/userprefs/templates/userprefs/section.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{% extends "twocols.html" %}{% load i18n uprefs_extras libextras %}
-{% block pagetitle %}{{ title }}{% endblock %}
-{% block html_head %}
-
-{% endblock %}
-{% block leftcol %}{% endblock %}
-{% block apparea %}
- {{ title }} {{ subtitle }}
-
-
-{% endblock %}
diff --git a/modoboa/userprefs/templatetags/uprefs_extras.py b/modoboa/userprefs/templatetags/uprefs_extras.py
index 8f162ea77..236a7a63e 100644
--- a/modoboa/userprefs/templatetags/uprefs_extras.py
+++ b/modoboa/userprefs/templatetags/uprefs_extras.py
@@ -12,16 +12,18 @@ register = template.Library()
def uprefs_menu(selection, user):
entries = [
{"name" : "profile",
- "url" : reverse("modoboa.userprefs.views.profile"),
+ "class" : "ajaxlink",
+ "url" : "profile/",
"label" : _("Profile")},
{"name" : "preferences",
- "url" : reverse("modoboa.userprefs.views.preferences"),
+ "class" : "ajaxlink",
+ "url" : "preferences/",
"label" : _("Preferences")},
]
- if user.group == 'SimpleUsers':
+ if user.group == 'SimpleUsers' and user.has_mailbox:
entries.insert(0, {"name" : "forward",
- "url" : reverse("modoboa.userprefs.views.forward"),
- "modalcb" : "forwardform_cb",
+ "class" : "ajaxlink",
+ "url" : "forward/",
"label" : _("Forward")})
entries += events.raiseQueryEvent("UserMenuDisplay", "uprefs_menu", user)
diff --git a/modoboa/userprefs/urls.py b/modoboa/userprefs/urls.py
index 4b26340b0..3a118ab59 100644
--- a/modoboa/userprefs/urls.py
+++ b/modoboa/userprefs/urls.py
@@ -1,4 +1,5 @@
from django.conf.urls.defaults import *
+from modoboa.lib import events
urlpatterns = patterns('modoboa.userprefs.views',
url(r'^$', 'index'),
@@ -6,3 +7,6 @@ urlpatterns = patterns('modoboa.userprefs.views',
(r'^profile/$', 'profile'),
(r'^forward/$', 'forward'),
)
+
+urlpatterns += patterns('',
+ *events.raiseQueryEvent("ExtraUprefsRoutes"))
diff --git a/modoboa/userprefs/views.py b/modoboa/userprefs/views.py
index e6758a3f1..3cdc9229b 100644
--- a/modoboa/userprefs/views.py
+++ b/modoboa/userprefs/views.py
@@ -9,6 +9,7 @@ from django.contrib.auth.decorators \
from django.conf import settings
from django.utils.translation import ugettext as _
from modoboa.lib import parameters, events
+from modoboa.lib.exceptions import ModoboaException
from modoboa.lib.webutils import ajax_response, ajax_simple_response
from forms import *
from modoboa.admin.models import Mailbox, Alias
@@ -16,19 +17,20 @@ from modoboa.admin.lib import AdminError
from modoboa.auth.lib import encrypt
@login_required
-def index(request):
- return HttpResponseRedirect(reverse(profile))
+def index(request, tplname="userprefs/index.html"):
+ extrajs = events.raiseQueryEvent("ExtraUprefsJS")
+ return render(request, tplname, {
+ "selection" : "user",
+ "extrajs" : "".join(extrajs)
+ })
@login_required
@user_passes_test(lambda u: u.belongs_to_group('SimpleUsers'))
-def forward(request):
- mb = request.user.mailbox_set.all()[0]
- ctx = dict(
- title=_("Forward"),
- subtitle=_("Automatically forward emails to another address"),
- action=reverse(forward),
- left_selection="forward",
- )
+def forward(request, tplname='userprefs/forward.html'):
+ try:
+ mb = request.user.mailbox_set.all()[0]
+ except IndexError:
+ raise ModoboaException(_("You need a mailbox in order to define a forward"))
try:
al = Alias.objects.get(address=mb.address,
domain__name=mb.domain.name)
@@ -53,10 +55,9 @@ def forward(request):
except BadDestination, e:
error = str(e)
- ctx.update(form=form, error=error)
return ajax_simple_response(dict(
status="ko",
- content=render_to_string("userprefs/form.html", dict(form=form)),
+ content=render_to_string(tplname, {"form" : form}),
respmsg=error
))
@@ -69,11 +70,15 @@ def forward(request):
pass
else:
form.fields["keepcopies"].initial = True
- ctx.update(form=form)
- return render(request, "userprefs/section.html", ctx)
+ return ajax_simple_response({
+ "status" : "ok",
+ "content" : render_to_string(tplname, {
+ "form" : form
+ })
+ })
@login_required
-def profile(request):
+def profile(request, tplname='userprefs/profile.html'):
update_password = True
if True in events.raiseQueryEvent("PasswordChange", request.user):
update_password = False
@@ -87,18 +92,17 @@ def profile(request):
return ajax_simple_response(dict(
status="ok", respmsg=_("Profile updated")
))
- return ajax_simple_response(dict(
- status="ko",
- content=render_to_string("userprefs/form.html", dict(form=form))
- ))
+ return ajax_simple_response({
+ "status" : "ko",
+ "content" : render_to_string(tplname, {"form" : form})
+ })
form = ProfileForm(update_password, instance=request.user)
- return render(request, 'userprefs/section.html', {
- "title" : _("Profile"),
- "subtitle" : _("Update your personal information"),
- "action" : reverse(profile),
- "left_selection" : "profile",
- "form" : form
+ return ajax_simple_response({
+ "status" : "ok",
+ "content" : render_to_string(tplname, {
+ "form" : form
+ })
})
@login_required
@@ -111,7 +115,7 @@ def preferences(request):
parameters.save_user(request.user, name, v, app=app)
return ajax_simple_response(dict(
- status="ok", message=_("Preferences saved")
+ status="ok", respmsg=_("Preferences saved")
))
apps = sorted(parameters._params.keys())
@@ -132,8 +136,9 @@ def preferences(request):
tmp["params"] += [newdef]
gparams += [tmp]
- return render(request, 'userprefs/preferences.html', {
- "selection" : "user",
- "left_selection" : "preferences",
- "gparams" : gparams
+ return ajax_simple_response({
+ "status" : "ok",
+ "content" : render_to_string("userprefs/preferences.html", {
+ "gparams" : gparams
+ })
})