diff --git a/admin/lib.py b/admin/lib.py
index 40b896dd2..d85a4f9cd 100644
--- a/admin/lib.py
+++ b/admin/lib.py
@@ -1,7 +1,26 @@
# coding: utf-8
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth.models import User, Group
+from django.utils.translation import ugettext as _
from models import *
+from modoboa.lib.webutils import _render_error
+
+def is_not_localadmin(errortpl="error"):
+ def dec(f):
+ def wrapped_f(request, *args, **kwargs):
+ if request.user.id == 1:
+ return _render_error(request, errortpl, {
+ "error" : _("Invalid action, %(user)s is a local user" \
+ % {"user" : request.user.username})
+ })
+ return f(request, *args, **kwargs)
+
+ wrapped_f.__name__ = f.__name__
+ wrapped_f.__dict__ = f.__dict__
+ wrapped_f.__doc__ = f.__doc__
+ wrapped_f.__module__ = f.__module__
+ return wrapped_f
+ return dec
def is_domain_admin(user):
"""Tell if a user is administrator for a domain of not
diff --git a/admin/models.py b/admin/models.py
index 36a8bf331..aed4cd235 100644
--- a/admin/models.py
+++ b/admin/models.py
@@ -5,8 +5,9 @@ from django.utils.translation import ugettext as _
from django.dispatch import receiver
from django.conf import settings
from modoboa.lib import parameters
-from modoboa.lib import exec_cmd, exec_as_vuser, crypt_password
+from modoboa.lib.sysutils import exec_cmd, exec_as_vuser
from modoboa.lib.emailutils import split_mailbox
+from modoboa.auth.lib import crypt_password
import os
import pwd
diff --git a/admin/permissions.py b/admin/permissions.py
index 60c38d821..01c4e2902 100644
--- a/admin/permissions.py
+++ b/admin/permissions.py
@@ -3,7 +3,7 @@
import datetime
from django.utils.translation import ugettext as _
from django.contrib.auth.models import User, Group
-from modoboa.lib import _render, getctx, _render_to_string
+from modoboa.lib.webutils import _render, getctx, _render_to_string
from forms import *
class Permissions(object):
diff --git a/admin/templatetags/admin_extras.py b/admin/templatetags/admin_extras.py
index 3670d87ae..c2a39923a 100644
--- a/admin/templatetags/admin_extras.py
+++ b/admin/templatetags/admin_extras.py
@@ -3,7 +3,8 @@ from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from modoboa import admin
-from modoboa.lib import events, static_url, render_actions
+from modoboa.lib import events
+from modoboa.lib.webutils import static_url, render_actions
register = template.Library()
diff --git a/admin/views.py b/admin/views.py
index 206429dd8..b3647dfc1 100644
--- a/admin/views.py
+++ b/admin/views.py
@@ -17,9 +17,10 @@ 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
+from modoboa.lib import events, parameters
+from modoboa.auth.lib import crypt_password
+from modoboa.lib.webutils \
+ import _render, ajax_response, ajax_simple_response, getctx
from modoboa.lib.emailutils import split_mailbox
from modoboa.lib.models import Parameter
import copy
diff --git a/auth/lib.py b/auth/lib.py
index 97c340792..6a6d921ea 100644
--- a/auth/lib.py
+++ b/auth/lib.py
@@ -1,5 +1,7 @@
# coding: utf-8
+import crypt, hashlib
+from random import Random
from Crypto.Cipher import AES
import base64
from modoboa.lib import parameters
@@ -22,3 +24,19 @@ def decrypt(ciph):
def get_password(request):
return decrypt(request.session["password"])
+def _check_password(password, crypted):
+ scheme = parameters.get_admin("PASSWORD_SCHEME", app="admin")
+ if scheme == "crypt":
+ return crypt.crypt(password, crypted) == crypted
+ if scheme == "md5":
+ return hashlib.md5(password).hexdigest() == crypted
+ return password
+
+def crypt_password(password):
+ scheme = parameters.get_admin("PASSWORD_SCHEME", app="admin")
+ if scheme == "crypt":
+ salt = ''.join(Random().sample(string.letters + string.digits, 2))
+ return crypt.crypt(password, salt)
+ if scheme == "md5":
+ return hashlib.md5(password).hexdigest()
+ return password
diff --git a/extensions/amavis_quarantine/main.py b/extensions/amavis_quarantine/main.py
index cf330f2a8..bfbc0d53a 100644
--- a/extensions/amavis_quarantine/main.py
+++ b/extensions/amavis_quarantine/main.py
@@ -5,7 +5,8 @@
from django.conf.urls.defaults import *
from django.utils.translation import ugettext as _, ungettext
from django.core.urlresolvers import reverse
-from modoboa.lib import events, parameters, static_url
+from modoboa.lib import events, parameters
+from modoboa.lib.webutils import static_url
def infos():
return {
diff --git a/extensions/amavis_quarantine/sql_listing.py b/extensions/amavis_quarantine/sql_listing.py
index 0f5572f1e..3a9cf9295 100644
--- a/extensions/amavis_quarantine/sql_listing.py
+++ b/extensions/amavis_quarantine/sql_listing.py
@@ -3,7 +3,8 @@
from datetime import datetime
from django.utils.translation import ugettext as _
from django.db.models import Q
-from modoboa.lib import tables, static_url
+from modoboa.lib import tables
+from modoboa.lib.webutils import static_url
from modoboa.lib.email_listing import MBconnector, EmailListing
from modoboa.lib.emailutils import *
from modoboa.admin.lib import is_domain_admin
diff --git a/extensions/amavis_quarantine/templatetags/amextras.py b/extensions/amavis_quarantine/templatetags/amextras.py
index 56996dd76..6618d139e 100644
--- a/extensions/amavis_quarantine/templatetags/amextras.py
+++ b/extensions/amavis_quarantine/templatetags/amextras.py
@@ -3,7 +3,7 @@ from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from django.conf import settings
-from modoboa.lib import static_url
+from modoboa.lib.webutils import static_url
from modoboa.extensions import amavis_quarantine
from modoboa.admin.lib import is_domain_admin
diff --git a/extensions/amavis_quarantine/views.py b/extensions/amavis_quarantine/views.py
index b9630077b..2b3a73210 100644
--- a/extensions/amavis_quarantine/views.py
+++ b/extensions/amavis_quarantine/views.py
@@ -9,13 +9,14 @@ from django.core.urlresolvers import reverse
from django.contrib.auth.decorators \
import login_required
from django.db.models import Q
-from modoboa.lib import parameters, _render, getctx, ajax_response
+from modoboa.lib import parameters
+from modoboa.lib.webutils import _render, getctx, ajax_response
from modoboa.admin.models import Mailbox
from lib import AMrelease
from templatetags.amextras import *
from modoboa.lib.email_listing import parse_search_parameters
from sql_listing import *
-from admin.lib import is_domain_admin
+from modoboa.admin.lib import is_domain_admin
def __get_current_url(request):
if request.session.has_key("page"):
diff --git a/extensions/postfix_autoreply/main.py b/extensions/postfix_autoreply/main.py
index f4bd8ff89..ca4ba700d 100644
--- a/extensions/postfix_autoreply/main.py
+++ b/extensions/postfix_autoreply/main.py
@@ -10,7 +10,8 @@ functionality into Postfix.
from django.conf.urls.defaults import include
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
-from modoboa.lib import events, parameters, static_url
+from modoboa.lib import events, parameters
+from modoboa.lib.webutils import static_url
from models import *
def infos():
diff --git a/extensions/postfix_autoreply/migrations/0002_auto__add_armessage__add_arhistoric.py b/extensions/postfix_autoreply/migrations/0002_auto__add_armessage__add_arhistoric.py
index 5a7fe478f..0f816e834 100644
--- a/extensions/postfix_autoreply/migrations/0002_auto__add_armessage__add_arhistoric.py
+++ b/extensions/postfix_autoreply/migrations/0002_auto__add_armessage__add_arhistoric.py
@@ -3,7 +3,7 @@ import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
-from modoboa.lib import db_table_exists
+from modoboa.lib.dbutils import db_table_exists
class Migration(SchemaMigration):
diff --git a/extensions/postfix_autoreply/views.py b/extensions/postfix_autoreply/views.py
index 580076fc0..abd67f25f 100644
--- a/extensions/postfix_autoreply/views.py
+++ b/extensions/postfix_autoreply/views.py
@@ -7,7 +7,8 @@ from django.contrib.auth.decorators \
from django.contrib import messages
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
-from modoboa.lib import _render, ajax_response, is_not_localadmin
+from modoboa.lib.webutils import _render, ajax_response
+from modoboa.admin.lib import is_not_localadmin
from forms import *
from models import *
diff --git a/extensions/sievefilters/main.py b/extensions/sievefilters/main.py
index d43c0e1a1..a753bcddf 100644
--- a/extensions/sievefilters/main.py
+++ b/extensions/sievefilters/main.py
@@ -2,7 +2,8 @@
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from django.conf.urls.defaults import include
-from modoboa.lib import events, parameters, static_url
+from modoboa.lib import events, parameters
+from modoboa.lib.webutils import static_url
from sievelib.managesieve import SUPPORTED_AUTH_MECHS
def init():
diff --git a/extensions/sievefilters/templatetags/sfilters_tags.py b/extensions/sievefilters/templatetags/sfilters_tags.py
index c924b346f..10e5ac0a9 100644
--- a/extensions/sievefilters/templatetags/sfilters_tags.py
+++ b/extensions/sievefilters/templatetags/sfilters_tags.py
@@ -3,7 +3,7 @@ from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from modoboa.extensions.sievefilters import views
-from modoboa.lib import render_actions
+from modoboa.lib.webutils import render_actions
register = template.Library()
diff --git a/extensions/sievefilters/views.py b/extensions/sievefilters/views.py
index 51adf8b01..f39fd0f83 100644
--- a/extensions/sievefilters/views.py
+++ b/extensions/sievefilters/views.py
@@ -4,8 +4,10 @@ from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
-from modoboa.lib import _render, _render_to_string, _render_error, \
- ajax_response, ajax_simple_response, is_not_localadmin, parameters
+from modoboa.lib import parameters
+from modoboa.lib.webutils import _render, _render_to_string, _render_error, \
+ ajax_response, ajax_simple_response
+from modoboa.admin.lib import is_not_localadmin
from modoboa.lib.connections import ConnectionError
from modoboa.auth.lib import get_password
from lib import *
diff --git a/extensions/stats/main.py b/extensions/stats/main.py
index 3372e4e42..1a11ffa3a 100644
--- a/extensions/stats/main.py
+++ b/extensions/stats/main.py
@@ -10,7 +10,8 @@ sent, received, bounced, rejected
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from django.conf.urls.defaults import *
-from modoboa.lib import events, parameters, static_url
+from modoboa.lib import events, parameters
+from modoboa.lib.webutils import static_url
def infos():
return {
diff --git a/extensions/stats/views.py b/extensions/stats/views.py
index ecb933ae5..0abe10575 100644
--- a/extensions/stats/views.py
+++ b/extensions/stats/views.py
@@ -4,7 +4,7 @@ from django.http import HttpResponse
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from django.utils import simplejson
-from modoboa.lib import _render, _render_to_string, getctx
+from modoboa.lib.webutils import _render, _render_to_string, getctx
from modoboa.admin.views import good_domain
from modoboa.admin.models import Domain, Mailbox
from django.contrib.auth.decorators \
diff --git a/extensions/webmail/lib.py b/extensions/webmail/lib.py
index 1e05fa761..f1c5c50b5 100644
--- a/extensions/webmail/lib.py
+++ b/extensions/webmail/lib.py
@@ -14,8 +14,8 @@ import email
import lxml
from django.utils.translation import ugettext as _
from django.conf import settings
-from modoboa.lib import decode, u2u_decode, tables, \
- imap_utf7, static_url, parameters
+from modoboa.lib import u2u_decode, tables, imap_utf7, parameters
+from modoboa.lib.webutils import static_url
from modoboa.lib.connections import ConnectionsManager
from modoboa.lib.email_listing import MBconnector, EmailListing
from modoboa.lib.emailutils import *
diff --git a/extensions/webmail/main.py b/extensions/webmail/main.py
index 88d6adf1c..77a86ec60 100644
--- a/extensions/webmail/main.py
+++ b/extensions/webmail/main.py
@@ -2,7 +2,8 @@
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from django.conf.urls.defaults import include
-from modoboa.lib import events, parameters, static_url
+from modoboa.lib import events, parameters
+from modoboa.lib.webutils import static_url
def init():
events.register("UserMenuDisplay", menu)
diff --git a/extensions/webmail/middleware.py b/extensions/webmail/middleware.py
index 2b3bd5089..528f65a99 100644
--- a/extensions/webmail/middleware.py
+++ b/extensions/webmail/middleware.py
@@ -1,6 +1,6 @@
# coding: utf-8
-from modoboa.lib import ajax_response
+from modoboa.lib.webutils import ajax_response
from modoboa.extensions.webmail.lib import WebmailError
class WebmailErrorMiddleware(object):
diff --git a/extensions/webmail/templatetags/webextras.py b/extensions/webmail/templatetags/webextras.py
index 92feb0a69..7c8dd1fd4 100644
--- a/extensions/webmail/templatetags/webextras.py
+++ b/extensions/webmail/templatetags/webextras.py
@@ -5,7 +5,8 @@ from django.core.urlresolvers import reverse
from django.conf import settings
from modoboa.extensions import webmail
from modoboa.extensions.webmail.lib import IMAPheader
-from modoboa.lib import parameters, static_url
+from modoboa.lib import parameters
+from modoboa.lib.webutils import static_url
register = template.Library()
diff --git a/extensions/webmail/views.py b/extensions/webmail/views.py
index edf8acb92..e916375a3 100644
--- a/extensions/webmail/views.py
+++ b/extensions/webmail/views.py
@@ -10,11 +10,12 @@ from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from modoboa.admin.models import Mailbox
-from modoboa.lib import parameters, _render, _render_error, \
- getctx, is_not_localadmin, _render_to_string, \
- ajax_response
+from modoboa.lib import parameters
+from modoboa.lib.webutils import _render, _render_error, \
+ getctx, _render_to_string, ajax_response
from modoboa.lib.emailutils import split_mailbox
from modoboa.lib.email_listing import parse_search_parameters, Paginator
+from modoboa.admin.lib import is_not_localadmin
from modoboa.auth.lib import *
from lib import *
from forms import *
diff --git a/lib/__init__.py b/lib/__init__.py
index 27999c802..e69de29bb 100644
--- a/lib/__init__.py
+++ b/lib/__init__.py
@@ -1,199 +0,0 @@
-# -*- coding: utf-8 -*-
-import os
-import sys
-import time
-import hashlib, crypt, string
-from random import Random
-from django.http import HttpResponse
-from django.conf import settings
-from django import template
-from django.shortcuts import render_to_response
-from django.template.loader import render_to_string
-from django.utils.translation import ugettext as _
-from django.utils import simplejson
-from modoboa.lib import parameters
-
-def exec_cmd(cmd, **kwargs):
- import subprocess
-
- p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, **kwargs)
- output = p.communicate()[0]
- return p.returncode, output
-
-def _render(request, tpl, user_context):
- """Custom rendering function
-
- Just a wrapper which automatically adds a RequestContext instance
- (useful to use settings variables like MEDIA_URL inside templates)
- """
- return render_to_response(tpl, user_context,
- context_instance=template.RequestContext(request))
-
-def _render_to_string(request, tpl, user_context):
- """Custom rendering function
-
- Same as _render.
- """
- return render_to_string(tpl, user_context,
- context_instance=template.RequestContext(request))
-
-def _render_error(request, errortpl="error", user_context={}):
- return render_to_response("common/%s.html" % errortpl, user_context,
- context_instance=template.RequestContext(request))
-
-def render_actions(actions):
- t = template.Template("""
-{% for a in actions %}
-
-
-
-{% endfor %}
-""")
- return t.render(template.Context({
- "actions" : actions
- }))
-
-def exec_as_vuser(cmd):
- code, output = exec_cmd("sudo -u %s %s" \
- % (parameters.get_admin("VIRTUAL_UID", app="admin"), cmd))
- if code:
- exec_cmd("echo '%s' >> /tmp/vmail.log" % output)
- return False
- return True
-
-def _ctx_ok(url):
- return {"status" : "ok", "url" : url}
-
-def _ctx_ko(tpl, ctx):
- return {"status" : "ko", "content" : render_to_string(tpl, ctx)}
-
-def static_url(path):
- """Returns the correct static url for a given file
-
- :param path: the targeted static media
- """
- if path.startswith("/"):
- path = path[1:]
- return "%s%s" % (settings.MEDIA_URL, path)
-
-def getctx(status, level=1, callback=None, **kwargs):
- if not callback:
- callername = sys._getframe(level).f_code.co_name
- else:
- callername = callback
- ctx = {"status" : status, "callback" : callername}
- for kw, v in kwargs.iteritems():
- ctx[kw] = v
- return ctx
-
-def ajax_response(request, status="ok", respmsg=None,
- url="", ajaxnav=False, norefresh=False,
- template=None, **kwargs):
- """Ajax response shortcut
-
- Simple shortcut that sends an JSON response. If a template is
- provided, a 'content' field will be added to the response,
- containing the result of this template rendering.
-
- :param request: a request object
- :param status: the response status ('ok' or 'ko)
- :param nexturl: url to display after receiving this response
- :param template: eventual template's path
- :param kwargs: dict used for template rendering
- """
- ctx = {}
- for k, v in kwargs.iteritems():
- ctx[k] = v
- if template is not None:
- content = _render_to_string(request, template, ctx)
- elif kwargs.has_key("content"):
- content = kwargs["content"]
- else:
- content = ""
- jsonctx = {"status" : status, "content" : content}
- if respmsg is not None:
- jsonctx["respmsg"] = respmsg
- if ajaxnav:
- jsonctx["ajaxnav"] = True
- if url != "":
- jsonctx["url"] = url
- jsonctx["norefresh"] = norefresh
- return HttpResponse(simplejson.dumps(jsonctx), mimetype="application/json")
-
-def ajax_simple_response(content):
- """Simple AJAX response
-
- No extra formatting is done. The content is passed directly to simplejon.
-
- :param content: the response's content (list, dict, string)
- """
- return HttpResponse(simplejson.dumps(content), mimetype="application/json")
-
-def decode(s, encodings=('utf8', 'latin1', 'windows-1252', 'ascii'), charset=None):
- if charset is not None:
- try:
- return s.decode(charset, 'ignore')
- except LookupError:
- pass
-
- for encoding in encodings:
- try:
- return s.decode(encoding)
- except UnicodeDecodeError:
- pass
- return s.decode('ascii', 'ignore')
-
-def is_not_localadmin(errortpl="error"):
- def dec(f):
- def wrapped_f(request, *args, **kwargs):
- if request.user.id == 1:
- return _render_error(request, errortpl, {
- "error" : _("Invalid action, %(user)s is a local user" \
- % {"user" : request.user.username})
- })
- return f(request, *args, **kwargs)
-
- wrapped_f.__name__ = f.__name__
- wrapped_f.__dict__ = f.__dict__
- wrapped_f.__doc__ = f.__doc__
- wrapped_f.__module__ = f.__module__
- return wrapped_f
- return dec
-
-def db_table_exists(table, cursor=None):
- """Check if table exists
-
- Taken from here:
- https://gist.github.com/527113/307c2dec09ceeb647b8fa1d6d49591f3352cb034
-
- """
- try:
- if not cursor:
- from django.db import connection
- cursor = connection.cursor()
- if not cursor:
- raise Exception
- table_names = connection.introspection.get_table_list(cursor)
- except:
- raise Exception("unable to determine if the table '%s' exists" % table)
- else:
- return table in table_names
-
-def _check_password(password, crypted):
- scheme = parameters.get_admin("PASSWORD_SCHEME", app="admin")
- if scheme == "crypt":
- return crypt.crypt(password, crypted) == crypted
- if scheme == "md5":
- return hashlib.md5(password).hexdigest() == crypted
- return password
-
-def crypt_password(password):
- scheme = parameters.get_admin("PASSWORD_SCHEME", app="admin")
- if scheme == "crypt":
- salt = ''.join(Random().sample(string.letters + string.digits, 2))
- return crypt.crypt(password, salt)
- if scheme == "md5":
- return hashlib.md5(password).hexdigest()
- return password
-
diff --git a/lib/authbackends.py b/lib/authbackends.py
index c2fafa886..d49235ccd 100644
--- a/lib/authbackends.py
+++ b/lib/authbackends.py
@@ -1,6 +1,6 @@
from django.contrib.auth.models import User
from modoboa.admin.models import Mailbox
-from modoboa.lib import _check_password
+from modoboa.auth.lib import _check_password
class SimpleBackend:
diff --git a/lib/dbutils.py b/lib/dbutils.py
new file mode 100644
index 000000000..738b9f6a6
--- /dev/null
+++ b/lib/dbutils.py
@@ -0,0 +1,20 @@
+# coding: utf-8
+from django.db import connection
+
+def db_table_exists(table, cursor=None):
+ """Check if table exists
+
+ Taken from here:
+ https://gist.github.com/527113/307c2dec09ceeb647b8fa1d6d49591f3352cb034
+
+ """
+ try:
+ if not cursor:
+ cursor = connection.cursor()
+ if not cursor:
+ raise Exception
+ table_names = connection.introspection.get_table_list(cursor)
+ except:
+ raise Exception("unable to determine if the table '%s' exists" % table)
+ else:
+ return table in table_names
diff --git a/lib/email_listing.py b/lib/email_listing.py
index 0bfbdab89..f85201f11 100644
--- a/lib/email_listing.py
+++ b/lib/email_listing.py
@@ -9,7 +9,8 @@ from django.conf import settings
from django.template.loader import render_to_string
from django.template import Template, Context
from django.utils.translation import ugettext as _
-from modoboa.lib import _render, decode
+from modoboa.lib.webutils import _render
+from modoboa.lib.emailutils import decode
attached_map = {}
diff --git a/lib/emailutils.py b/lib/emailutils.py
index ed7bfbfa0..2a6f0102d 100644
--- a/lib/emailutils.py
+++ b/lib/emailutils.py
@@ -7,7 +7,6 @@ import lxml
from django.template import Template, Context
from django.template.loader import render_to_string
import u2u_decode
-from modoboa.lib import decode
class EmailAddress(object):
def __init__(self, address):
@@ -196,3 +195,17 @@ def split_mailbox(mailbox):
domain = parts[-1]
address = "@".join(parts[:-1])
return (address, domain)
+
+def decode(s, encodings=('utf8', 'latin1', 'windows-1252', 'ascii'), charset=None):
+ if charset is not None:
+ try:
+ return s.decode(charset, 'ignore')
+ except LookupError:
+ pass
+
+ for encoding in encodings:
+ try:
+ return s.decode(encoding)
+ except UnicodeDecodeError:
+ pass
+ return s.decode('ascii', 'ignore')
diff --git a/lib/models.py b/lib/models.py
index 03098b980..9e58b5ace 100644
--- a/lib/models.py
+++ b/lib/models.py
@@ -6,6 +6,6 @@ class Parameter(models.Model):
value = models.CharField(max_length=255)
class UserParameter(models.Model):
- user = models.ForeignKey(User)
+ user = models.ForeignKey("auth.User")
name = models.CharField(max_length=255)
value = models.CharField(max_length=255)
diff --git a/lib/parameters.py b/lib/parameters.py
index f6ba8c127..8134f6e85 100644
--- a/lib/parameters.py
+++ b/lib/parameters.py
@@ -3,7 +3,6 @@
import string
import inspect
import re
-from modoboa.lib.models import *
"""
This interface provides a simple way to declare and store parameters
@@ -76,6 +75,8 @@ def unregister_app(app):
return True
def save_admin(name, value, app=None):
+ from models import Parameter
+
if app is None:
app = __guess_extension()
__is_defined(app, 'A', name)
@@ -91,6 +92,8 @@ def save_admin(name, value, app=None):
return True
def save_user(user, name, value, app=None):
+ from models import UserParameter
+
if app is None:
app = __guess_extension()
__is_defined(app, 'U', name)
@@ -107,6 +110,8 @@ def save_user(user, name, value, app=None):
return True
def get_admin(name, app=None):
+ from models import Parameter
+
if app is None:
app = __guess_extension()
__is_defined(app, "A", name)
@@ -117,6 +122,8 @@ def get_admin(name, app=None):
return p.value.decode("string_escape")
def get_user(user, name, app=None):
+ from models import UserParameter
+
if app is None:
app = __guess_extension()
__is_defined(app, "U", name)
diff --git a/lib/sysutils.py b/lib/sysutils.py
new file mode 100644
index 000000000..efa73c957
--- /dev/null
+++ b/lib/sysutils.py
@@ -0,0 +1,23 @@
+# coding: utf-8
+
+"""
+This module extra functions/shortcuts to communicate with the system
+(executing commands, etc.)
+"""
+
+from modoboa.lib import parameters
+
+def exec_cmd(cmd, **kwargs):
+ import subprocess
+
+ p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, **kwargs)
+ output = p.communicate()[0]
+ return p.returncode, output
+
+def exec_as_vuser(cmd):
+ code, output = exec_cmd("sudo -u %s %s" \
+ % (parameters.get_admin("VIRTUAL_UID", app="admin"), cmd))
+ if code:
+ exec_cmd("echo '%s' >> /tmp/vmail.log" % output)
+ return False
+ return True
diff --git a/lib/templatetags/libextras.py b/lib/templatetags/libextras.py
index 1fa90af2c..ed04ba605 100644
--- a/lib/templatetags/libextras.py
+++ b/lib/templatetags/libextras.py
@@ -3,7 +3,7 @@ import os
from django.conf import settings
from django import template
from django.contrib import messages
-from modoboa.lib import exec_cmd
+from modoboa.lib.sysutils import exec_cmd
register = template.Library()
diff --git a/lib/webutils.py b/lib/webutils.py
new file mode 100644
index 000000000..a05380bc1
--- /dev/null
+++ b/lib/webutils.py
@@ -0,0 +1,114 @@
+# coding: utf-8
+
+"""
+This module contains extra functions/shortcuts used to render HTML.
+"""
+import sys
+from django.http import HttpResponse
+from django.shortcuts import render_to_response
+from django.template.loader import render_to_string
+from django import template
+from django.utils import simplejson
+from django.conf import settings
+
+def _render(request, tpl, user_context):
+ """Custom rendering function
+
+ Just a wrapper which automatically adds a RequestContext instance
+ (useful to use settings variables like MEDIA_URL inside templates)
+ """
+ return render_to_response(tpl, user_context,
+ context_instance=template.RequestContext(request))
+
+def _render_to_string(request, tpl, user_context):
+ """Custom rendering function
+
+ Same as _render.
+ """
+ return render_to_string(tpl, user_context,
+ context_instance=template.RequestContext(request))
+
+def _render_error(request, errortpl="error", user_context={}):
+ return render_to_response("common/%s.html" % errortpl, user_context,
+ context_instance=template.RequestContext(request))
+
+def render_actions(actions):
+ t = template.Template("""
+{% for a in actions %}
+
+
+
+{% endfor %}
+""")
+ return t.render(template.Context({
+ "actions" : actions
+ }))
+
+def _ctx_ok(url):
+ return {"status" : "ok", "url" : url}
+
+def _ctx_ko(tpl, ctx):
+ return {"status" : "ko", "content" : render_to_string(tpl, ctx)}
+
+def getctx(status, level=1, callback=None, **kwargs):
+ if not callback:
+ callername = sys._getframe(level).f_code.co_name
+ else:
+ callername = callback
+ ctx = {"status" : status, "callback" : callername}
+ for kw, v in kwargs.iteritems():
+ ctx[kw] = v
+ return ctx
+
+def ajax_response(request, status="ok", respmsg=None,
+ url="", ajaxnav=False, norefresh=False,
+ template=None, **kwargs):
+ """Ajax response shortcut
+
+ Simple shortcut that sends an JSON response. If a template is
+ provided, a 'content' field will be added to the response,
+ containing the result of this template rendering.
+
+ :param request: a request object
+ :param status: the response status ('ok' or 'ko)
+ :param nexturl: url to display after receiving this response
+ :param template: eventual template's path
+ :param kwargs: dict used for template rendering
+ """
+ ctx = {}
+ for k, v in kwargs.iteritems():
+ ctx[k] = v
+ if template is not None:
+ content = _render_to_string(request, template, ctx)
+ elif kwargs.has_key("content"):
+ content = kwargs["content"]
+ else:
+ content = ""
+ jsonctx = {"status" : status, "content" : content}
+ if respmsg is not None:
+ jsonctx["respmsg"] = respmsg
+ if ajaxnav:
+ jsonctx["ajaxnav"] = True
+ if url != "":
+ jsonctx["url"] = url
+ jsonctx["norefresh"] = norefresh
+ return HttpResponse(simplejson.dumps(jsonctx), mimetype="application/json")
+
+def ajax_simple_response(content):
+ """Simple AJAX response
+
+ No extra formatting is done. The content is passed directly to simplejon.
+
+ :param content: the response's content (list, dict, string)
+ """
+ return HttpResponse(simplejson.dumps(content), mimetype="application/json")
+
+def static_url(path):
+ """Returns the correct static url for a given file
+
+ :param path: the targeted static media
+ """
+ if path.startswith("/"):
+ path = path[1:]
+ return "%s%s" % (settings.MEDIA_URL, path)
diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po
index a42f01d4a..613995c20 100644
--- a/locale/de/LC_MESSAGES/django.po
+++ b/locale/de/LC_MESSAGES/django.po
@@ -5,7 +5,7 @@
# Patrick Ben Koetter
, 2010-2011. msgid "" msgstr "" -"Project-Id-Version: Modoboa-0.8.5\n" +"Project-Id-Version: Modoboa-0.8.6\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-08-25 09:53+0200\n" "PO-Revision-Date: 2011-08-25 13:03+0100\n" diff --git a/locale/de/LC_MESSAGES/djangojs.po b/locale/de/LC_MESSAGES/djangojs.po index 3e2db2121..31201d7fb 100644 --- a/locale/de/LC_MESSAGES/djangojs.po +++ b/locale/de/LC_MESSAGES/djangojs.po @@ -5,7 +5,7 @@ # Patrick Ben Koetter
, 2010-2011. msgid "" msgstr "" -"Project-Id-Version: Modoboa-0.8.5\n" +"Project-Id-Version: Modoboa-0.8.6\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-08-25 09:58+0200\n" "PO-Revision-Date: 2011-07-10 07:30+0000\n" diff --git a/tools/pfxadmin_migrate/migrate.py b/tools/pfxadmin_migrate/migrate.py index a5a1140ba..0bce33811 100755 --- a/tools/pfxadmin_migrate/migrate.py +++ b/tools/pfxadmin_migrate/migrate.py @@ -48,7 +48,7 @@ from django.db.models import Q from django.contrib.auth.models import Group import modoboa.admin.models as md_models import models as pf_models -from modoboa.lib import exec_cmd +from modoboa.lib.sysutils import exec_cmd from modoboa.lib.emailutils import split_mailbox def migrate_dates(oldobj): diff --git a/userprefs/forms.py b/userprefs/forms.py index 72c987f2d..ec6196d15 100644 --- a/userprefs/forms.py +++ b/userprefs/forms.py @@ -1,6 +1,6 @@ from django import forms from modoboa.admin.models import Domain, Mailbox -from modoboa.lib import _check_password +from modoboa.auth.lib import _check_password from django.contrib.auth.models import check_password from django.utils.translation import ugettext as _ from modoboa.lib.emailutils import split_mailbox diff --git a/userprefs/templatetags/uprefs_extras.py b/userprefs/templatetags/uprefs_extras.py index 9a844f754..3c34858a3 100644 --- a/userprefs/templatetags/uprefs_extras.py +++ b/userprefs/templatetags/uprefs_extras.py @@ -3,7 +3,8 @@ from django.template.loader import render_to_string from django.utils.translation import ugettext as _ from django.core.urlresolvers import reverse from modoboa import userprefs -from modoboa.lib import events, static_url +from modoboa.lib import events +from modoboa.lib.webutils import static_url from modoboa.admin.lib import is_domain_admin register = template.Library() diff --git a/userprefs/views.py b/userprefs/views.py index 26bb61c7b..cab96d0c5 100644 --- a/userprefs/views.py +++ b/userprefs/views.py @@ -4,12 +4,12 @@ from django.http import HttpResponseRedirect from django.contrib.auth.decorators \ import login_required, user_passes_test from django.utils.translation import ugettext as _ -from modoboa.lib import _render, ajax_response, parameters -from modoboa.lib import crypt_password +from modoboa.lib import parameters +from modoboa.lib.webutils import _render, ajax_response from forms import * from modoboa.admin.models import Mailbox, Alias from modoboa.admin.lib import is_domain_admin -from modoboa.auth.lib import encrypt +from modoboa.auth.lib import encrypt, crypt_password @login_required def index(request):