mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
* see #92: Some graphical fixes,
* Documentation update, * Ugly hacks to make the stats plugin work as before.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009-2010, Antoine Nguyen <tonio@ngyn.org>
|
||||
Copyright (c) 2009-2011, 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
|
||||
|
||||
@@ -39,7 +39,7 @@ Initialize the database by running the following command::
|
||||
|
||||
$ python manage.py syncdb
|
||||
|
||||
It will let you create the default super adminstrator.
|
||||
It will let you create the default super administrator.
|
||||
|
||||
Since version 0.8, Modoboa is using *south* to handle schema
|
||||
migrations. To finish the database initialization, you must
|
||||
@@ -115,6 +115,8 @@ existing database.**
|
||||
|
||||
$ python manage.py migrate admin
|
||||
|
||||
#. Update SQL queries used in your environnement (see :ref:`postfix-label` or :ref:`dovecot-label`).
|
||||
|
||||
|
||||
0.8.2: ckeditor integration and more
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -129,7 +131,7 @@ existing database.**
|
||||
#. Download the latest release of ckeditor and extract it into *<modoboa_dir>/static/js/*. It should create a new directory named *ckeditor*.
|
||||
#. Update the following variables inside *settings.py*::
|
||||
|
||||
MEDIA_ROOT = os.path.join(MODOBOA_DIR, '/static')
|
||||
MEDIA_ROOT = os.path.join(MODOBOA_DIR, 'static')
|
||||
MEDIA_URL = '/static/'
|
||||
|
||||
#. Then, add the following variable: ``MODOBOA_WEBPATH = 'modoboa/'``
|
||||
@@ -187,15 +189,17 @@ Finally, run the following commands::
|
||||
$ python manage.py migrate --all 0001 --fake
|
||||
$ python manage.py migrate --all 0002
|
||||
|
||||
0.7 : no SQL modifications
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
0.7 : Nothing to do
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
0.6 : no SQL modifications
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
0.6 : Nothing to do
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Integrating Modoboa with other softwares
|
||||
========================================
|
||||
|
||||
.. _postfix-label:
|
||||
|
||||
Postfix
|
||||
-------
|
||||
|
||||
@@ -216,7 +220,7 @@ First, define the following map files on your server (it should work with
|
||||
password = <password>
|
||||
dbname = <database>
|
||||
hosts = 127.0.0.1
|
||||
query = SELECT path FROM admin_mailbox WHERE full_address = '%s'
|
||||
query = SELECT concat(t2.name, '/', t1.path) FROM admin_mailbox AS t1, admin_domain AS t2 WHERE t1.domain_id=t2.id AND t1.address='%u' AND t2.name='%d'
|
||||
|
||||
``/etc/postfix/sql-aliases.cf``::
|
||||
|
||||
@@ -224,7 +228,7 @@ First, define the following map files on your server (it should work with
|
||||
password = <password>
|
||||
dbname = <database>
|
||||
hosts = 127.0.0.1
|
||||
query = SELECT t3.full_address FROM admin_alias AS t1, admin_alias_mboxes AS t2, admin_mailbox AS t3 WHERE t1.full_address='%s' AND t1.id=t2.alias_id AND t2.mailbox_id=t3.id AND t1.enabled='1'
|
||||
query = SELECT concat(t3.address, '@', t4.name) FROM admin_alias AS t1, admin_alias_mboxes AS t2, admin_mailbox AS t3, admin_domain AS t4 WHERE t1.enabled='1' AND t1.address='%u' AND t1.id=t2.alias_id AND t2.mailbox_id=t3.id AND t3.domain_id=t4.id AND t4.name='%d'
|
||||
|
||||
Then, use the following configuration in the */etc/postfix/main.cf* file
|
||||
(this is just one possible configuration)::
|
||||
@@ -248,6 +252,8 @@ NB: Modoboa supports both maildir and mbox formats. You can specify
|
||||
which format to use by modifying the MAILBOX_TYPE parameter available
|
||||
in the admin panel.
|
||||
|
||||
.. _dovecot-label:
|
||||
|
||||
Dovecot
|
||||
-------
|
||||
|
||||
@@ -281,7 +287,7 @@ following content inside::
|
||||
# ... stuff after
|
||||
}
|
||||
|
||||
Be sure to activate only one backend (per type) inside your configuration
|
||||
Make sure to activate only one backend (per type) inside your configuration
|
||||
(just comment the other ones).
|
||||
|
||||
Then, edit your */etc/dovecot/dovecot-sql.conf* and modify following lines::
|
||||
@@ -289,8 +295,8 @@ Then, edit your */etc/dovecot/dovecot-sql.conf* and modify following lines::
|
||||
driver = mysql
|
||||
connect = host=<mysqld socket> dbname=<database> user=<user> password=<password>
|
||||
default_pass_scheme = CRYPT
|
||||
password_query = SELECT full_address AS user, password FROM admin_mailbox WHERE full_address = '%u'
|
||||
user_query = SELECT path AS home, uid, gid FROM admin_mailbox WHERE full_address = '%u'
|
||||
password_query = SELECT concat(t1.address, t2.name) AS user, password FROM admin_mailbox AS t1, admin_domain AS t2 WHERE t1.domain_id=t2.id AND t1.address='%n' AND t2.name='%d'
|
||||
user_query = SELECT concat(t2.name, '/', t1.path) AS home, uid, gid FROM admin_mailbox AS t1, admin_domain AS t2 WHERE WHERE t1.domain_id=t2.id AND t1.address='%n' AND t2.name='%d'
|
||||
|
||||
Enable quotas support
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -317,7 +323,7 @@ If you use version prior to 1.1, add also the following configuration::
|
||||
Then, modify the above query inside *dovecot-sql.conf* as follow to
|
||||
activate per user quotas::
|
||||
|
||||
user_query = SELECT path AS home, uid, gid, concat('<backend>:storage=', quota / 1024) AS quota FROM admin_mailbox WHERE full_address = '%u'
|
||||
user_query = SELECT concat(t2.name, '/', t1.path) AS home, uid, gid, concat('<backend>:storage=', quota / 1024) AS quota FROM admin_mailbox AS t1, admin_domain AS t2 WHERE t1.domain_id=t2.id AND t1.address='%n' AND t2.name='%d'
|
||||
|
||||
If you are not using MySQL, you will have to replace the ``concat``
|
||||
function call with something working with your database.
|
||||
@@ -334,7 +340,7 @@ For version >= 1.1, put the following configuration inside the *dovecot.conf* fi
|
||||
Then, modify the above query inside *dovecot-sql.conf* to activate
|
||||
user quotas::
|
||||
|
||||
user_query = SELECT path AS home, uid, gid, concat('*:storage=', quota, 'M') AS quota_rule FROM admin_mailbox WHERE full_address = '%u'
|
||||
user_query = SELECT concat(t2.name, '/', t1.path) AS home, uid, gid, concat('*:storage=', quota, 'M') AS quota_rule FROM admin_mailbox AS t1, admin_domain AS t2 WHERE t1.domain_id=t2.id AND t1.address='%n' AND t2.name='%d'
|
||||
|
||||
How to serve Modoboa behind a webserver
|
||||
=======================================
|
||||
@@ -364,6 +370,9 @@ following inside::
|
||||
This is one possible configuration. Note that you will certainly need more
|
||||
configuration in order to launch Apache.
|
||||
|
||||
Nginx
|
||||
-----
|
||||
|
||||
Using default plugins
|
||||
=====================
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ Available components:
|
||||
Django is needed to use Modoboa (http://www.djangoproject.com/)
|
||||
|
||||
The following external tools are provided with Modoboa:
|
||||
* Mootools version 1.2+ (http://www.mootools.net/),
|
||||
* Mootools version 1.3+ (http://www.mootools.net/),
|
||||
* SqueezeBox version 1.1+ (http://digitarald.de/project/squeezebox/),
|
||||
* Calendar (http://electricprism.com/aeron/calendar/)
|
||||
|
||||
|
||||
+2
-2
@@ -152,12 +152,12 @@ class SuperAdminsTable(tables.Table):
|
||||
selection = tables.SelectionColumn("selection", width="4%", first=True)
|
||||
_1_user_name = tables.Column("user_name", label=_("User name"))
|
||||
_2_full_name = tables.Column("full_name", label=_("Full name"))
|
||||
_3_enabled = tables.Column("enabled", label=_("Enabled_m"), width="10%")
|
||||
_3_enabled = tables.Column("enabled", label=gender("Enabled", "m"), width="10%")
|
||||
|
||||
class DomainAdminsTable(tables.Table):
|
||||
idkey = "id"
|
||||
selection = tables.SelectionColumn("selection", width="4%", first=True)
|
||||
_1_domain = tables.Column("domain", label=_("Domain"))
|
||||
_2_full_name = tables.Column("full_name", label=_("Full name"))
|
||||
_3_enabled = tables.Column("enabled", label=_("Enabled_m"), width="10%")
|
||||
_3_enabled = tables.Column("enabled", label=gender("Enabled", "m"), width="10%")
|
||||
|
||||
|
||||
@@ -87,12 +87,19 @@ def dommenu_entry(name, label, img, listurl, newurl):
|
||||
def domains_menu(selection, user, domid):
|
||||
args = domid != "" and ("?domid=%s" % domid) or ""
|
||||
entries = []
|
||||
if selection == "stats":
|
||||
disabled = True
|
||||
else:
|
||||
disabled = False
|
||||
|
||||
entries += [{"name" : "new",
|
||||
"label" : _("New"),
|
||||
"img" : static_url("pics/add.png")},
|
||||
"img" : static_url("pics/add.png"),
|
||||
"disabled" : disabled},
|
||||
{"name" : "remove",
|
||||
"label" : _("Remove"),
|
||||
"img" : static_url("pics/remove.png")
|
||||
"img" : static_url("pics/remove.png"),
|
||||
"disabled" : disabled
|
||||
}]
|
||||
|
||||
entries += [{"separator" : True}]
|
||||
|
||||
@@ -450,6 +450,7 @@ def permissions(request, tplname='admin/permissions.html'):
|
||||
permtables += [
|
||||
{"id" : "super_admins",
|
||||
"title" : _("Super administrators"),
|
||||
"rel" : "300 140",
|
||||
"content" : SuperAdminsPerms().get(request)}
|
||||
]
|
||||
|
||||
@@ -458,6 +459,7 @@ def permissions(request, tplname='admin/permissions.html'):
|
||||
permtables += [
|
||||
{"id" : "domain_admins",
|
||||
"title" : _("Domain administrators"),
|
||||
"rel" : "300 180",
|
||||
"content" : DomainAdminsPerms().get(request)}
|
||||
]
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ window.addEvent("domready", function() {
|
||||
} else {
|
||||
infobox.error(resp.error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
get_period = function() {
|
||||
if ($("period").value != "custom") {
|
||||
@@ -55,7 +55,7 @@ window.addEvent("domready", function() {
|
||||
return "period=custom"
|
||||
+ "&start=" + $("dateTravelStart").value
|
||||
+ "&end=" + $("dateTravelEnd").value;
|
||||
}
|
||||
};
|
||||
|
||||
get_graph = function(evt) {
|
||||
{% if user.is_superuser %}
|
||||
@@ -70,7 +70,7 @@ window.addEvent("domready", function() {
|
||||
}
|
||||
new Request.JSON({url : url + "?" + p, noCache: true,
|
||||
onSuccess : getgraph_callback}).get();
|
||||
}
|
||||
};
|
||||
|
||||
{% if user.is_superuser %}
|
||||
$("domain").addEvent("change", get_graph);
|
||||
|
||||
@@ -25,12 +25,12 @@ periods = [{"name" : "day", "label" : _("Day")},
|
||||
@good_domain
|
||||
@permission_required("admin.view_mailboxes")
|
||||
def index(request):
|
||||
domain = None
|
||||
domains = None
|
||||
period = request.GET.has_key("period") and request.GET["period"] or "day"
|
||||
domid = request.GET.has_key("domid") and request.GET["domid"] or ""
|
||||
if request.user.is_superuser:
|
||||
domains = Domain.objects.all()
|
||||
domain = "global"
|
||||
else:
|
||||
domain = Domain.objects.get(pk=domid)
|
||||
|
||||
|
||||
@@ -2,11 +2,13 @@ window.addEvent('domready', function() {
|
||||
var tip = new Tips($$(".Tips"));
|
||||
|
||||
var current_role = "";
|
||||
var current_sizes = "";
|
||||
var accordion = new Accordion('h3.atStart', 'div.atStart', {
|
||||
opacity: true,
|
||||
onActive: function(toggler, element){
|
||||
toggler.setStyle('color', '#ff3300');
|
||||
current_role = element.get("id");
|
||||
current_sizes = element.get("rel");
|
||||
},
|
||||
|
||||
onBackground: function(toggler, element) {
|
||||
@@ -16,8 +18,9 @@ window.addEvent('domready', function() {
|
||||
|
||||
$$("a[name=addperm]").addEvent("click", function(evt) {
|
||||
evt.stop();
|
||||
var sizes = current_sizes.split(" ");
|
||||
SqueezeBox.initialize({
|
||||
size: {x: 300, y: 280},
|
||||
size: {x: sizes[0], y: sizes[1]},
|
||||
handler: 'iframe'
|
||||
});
|
||||
var addperm_url = evt.target.get("href") + "?role=" + current_role;
|
||||
|
||||
@@ -42,7 +42,7 @@ window.addEvent("domready", function() {
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block middletitle %}
|
||||
{% block pagetitle %}{% endblock %}{% if domain %} ({% trans "for" %} {{ domain.name }}){% endif %}
|
||||
{% block pagetitle %}{% endblock %}{% if domain and domain != "global" %} ({% trans "for" %} {{ domain.name }}){% endif %}
|
||||
{% endblock %}
|
||||
{% block menu %}{% domains_menu selection user domid %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<div id="accordion">
|
||||
{% for table in permtables %}
|
||||
<h3 class="toggler atStart">{{ table.title }}</h3>
|
||||
<div class="element atStart" id="{{ table.id }}">
|
||||
<div class="element atStart" id="{{ table.id }}" rel="{{ table.rel }}">
|
||||
{{ table.content }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
@@ -26,14 +26,15 @@
|
||||
</li>
|
||||
{% else %}
|
||||
<li {% if selection == entry.name %}class="selected"{% endif %}>
|
||||
{% if not entry.disabled %}
|
||||
<a href="{{ entry.url }}" name="{{ entry.name }}"
|
||||
{% if entry.class %}class={{ entry.class }}{% endif %}
|
||||
{% if entry.rel %}rel={{ entry.rel }}{% endif %}
|
||||
{% if entry.confirm %} onclick="return confirm('{{ entry.confirm }}')"{% endif %}>
|
||||
|
||||
{% if entry.img %}<img src="{{ entry.img }}" alt="" />{% endif %}
|
||||
{{ entry.label }}
|
||||
</a>
|
||||
{% if entry.class %}class={{ entry.class }}{% endif %}
|
||||
{% if entry.rel %}rel={{ entry.rel }}{% endif %}
|
||||
{% if entry.confirm %} onclick="return confirm('{{ entry.confirm }}')"{% endif %}>
|
||||
{% endif %}
|
||||
{% if entry.img %}<img src="{{ entry.img }}" alt="" />{% endif %}
|
||||
{{ entry.label }}
|
||||
{% if not entry.disabled %}</a>{% endif %}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user