mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
#48 : rollback, this is not trivial.
This commit is contained in:
@@ -112,56 +112,3 @@ class Alias(models.Model):
|
||||
("view_aliases", "View aliases"),
|
||||
)
|
||||
|
||||
class Extension(models.Model):
|
||||
name = models.CharField(max_length=150)
|
||||
enabled = models.BooleanField(_('enabled'),
|
||||
help_text=_("Check to enable this extension"))
|
||||
has_templates = models.BooleanField()
|
||||
|
||||
def on(self):
|
||||
from django.core.management import sql, color
|
||||
from django.db import connection, models
|
||||
|
||||
style = color.no_style()
|
||||
cursor = connection.cursor()
|
||||
module = __import__("mailng.extensions.%s" % self.name,
|
||||
globals(), locals(), ['main', 'models'])
|
||||
try:
|
||||
extmodels = module.models
|
||||
except AttributeError:
|
||||
extmodels = None
|
||||
if extmodels is not None:
|
||||
mods = []
|
||||
for k, v in extmodels.__dict__.iteritems():
|
||||
try:
|
||||
if not issubclass(v, models.Model):
|
||||
continue
|
||||
statements, pending = \
|
||||
connection.creation.sql_create_model(v, style)
|
||||
try:
|
||||
for sql in statements:
|
||||
cursor.execute(sql)
|
||||
except Exception, msg:
|
||||
pass
|
||||
except TypeError:
|
||||
pass
|
||||
if self.has_templates:
|
||||
code, output = exec_cmd("ln -s ../extensions/%s/templates templates/%s" \
|
||||
% (self.name, self.name))
|
||||
if os.path.exists("extensions/%s/scripts" % self.name):
|
||||
code, output = exec_cmd("ln -s ../extensions/%s/scripts scripts/%s" \
|
||||
% (self.name, self.name))
|
||||
module.main.init()
|
||||
self.enabled = True
|
||||
self.save()
|
||||
|
||||
def off(self):
|
||||
if self.has_templates:
|
||||
code, output = exec_cmd("rm -f templates/%s" % self.name)
|
||||
print output
|
||||
self.enabled = False
|
||||
self.save()
|
||||
module = __import__("mailng.extensions.%s" % self.name,
|
||||
globals(), locals(), ['main', 'models'])
|
||||
module.main.destroy()
|
||||
|
||||
|
||||
@@ -62,9 +62,6 @@ def settings_menu(selection, user):
|
||||
"url" : reverse(admin.views.viewparameters),
|
||||
"img" : "/static/pics/domains.png",
|
||||
"label" : _("Parameters")},
|
||||
{"name" : "extensions",
|
||||
"url" : reverse(admin.views.viewextensions),
|
||||
"label" : _("Extensions")},
|
||||
]
|
||||
return render_to_string('common/menu.html',
|
||||
{"selection" : selection, "entries" : entries,
|
||||
|
||||
@@ -19,8 +19,6 @@ urlpatterns = patterns('mailng.admin.views',
|
||||
(r'^settings/$', 'settings'),
|
||||
(r'^settings/addperm/$', 'addpermission'),
|
||||
(r'^settings/delperm/(?P<mbox_id>\d+)/(?P<group>\w+)/$', 'deletepermission'),
|
||||
(r'^settings/extensions/$', 'viewextensions'),
|
||||
(r'^settings/extensions/save/$', 'saveextensions'),
|
||||
(r'^settings/parameters/$', 'viewparameters'),
|
||||
(r'^settings/parameters/save/$', 'saveparameters'),
|
||||
)
|
||||
|
||||
+1
-53
@@ -12,7 +12,7 @@ from django.contrib.auth.decorators \
|
||||
import login_required, permission_required, user_passes_test
|
||||
from django.contrib.auth.models import User, Group
|
||||
from mailng import admin, userprefs
|
||||
from mailng.admin.models import Domain, Mailbox, Alias, Extension
|
||||
from mailng.admin.models import Domain, Mailbox, Alias
|
||||
from forms import MailboxForm, DomainForm, AliasForm, PermissionForm
|
||||
from mailng.lib.authbackends import crypt_password
|
||||
from mailng.lib import _render, _ctx_ok, _ctx_ko
|
||||
@@ -440,55 +440,3 @@ def saveparameters(request):
|
||||
parameters.save(app, name, v)
|
||||
request.user.message_set.create(message=_("Configuration saved."))
|
||||
return HttpResponseRedirect(reverse(admin.views.viewparameters))
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
def viewextensions(request):
|
||||
from mailng.extensions import list_extensions
|
||||
from mailng.lib import tables
|
||||
|
||||
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"))
|
||||
|
||||
exts = list_extensions()
|
||||
for ext in exts:
|
||||
try:
|
||||
dbext = Extension.objects.get(name=ext["id"])
|
||||
ext["selection"] = dbext.enabled
|
||||
except Extension.DoesNotExist:
|
||||
dbext = Extension()
|
||||
dbext.name = ext["id"]
|
||||
dbext.enabled = False
|
||||
dbext.has_templates = ext["templates"]
|
||||
dbext.save()
|
||||
ext["selection"] = False
|
||||
|
||||
tbl = ExtensionsTable(exts)
|
||||
return _render(request, 'admin/extensions.html', {
|
||||
"extensions" : tbl.render(request)
|
||||
})
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
def saveextensions(request):
|
||||
from mailng import extensions
|
||||
|
||||
actived_exts = Extension.objects.filter(enabled=True)
|
||||
found = []
|
||||
for k, v in request.POST.iteritems():
|
||||
if k.startswith("select_"):
|
||||
parts = k.split("_", 1)
|
||||
dbext = Extension.objects.get(name=parts[1])
|
||||
if not dbext in actived_exts:
|
||||
dbext.on()
|
||||
else:
|
||||
found += [dbext]
|
||||
for ext in actived_exts:
|
||||
if not ext in found:
|
||||
ext.off()
|
||||
|
||||
return HttpResponseRedirect(reverse(admin.views.viewextensions))
|
||||
|
||||
+12
-50
@@ -1,61 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import re
|
||||
|
||||
extensions = {}
|
||||
from django.conf import settings
|
||||
|
||||
def loadextensions():
|
||||
from admin.models import Extension
|
||||
from django.template import add_to_builtins
|
||||
|
||||
exts = Extension.objects.filter(enabled=True)
|
||||
for ext in exts:
|
||||
tagsdir = "extensions/%s/templatetags" % ext.name
|
||||
if os.path.isdir("extensions/%s/templatetags" % ext.name):
|
||||
for f in os.listdir(tagsdir):
|
||||
if f in ["__init__.py", "__init__.pyc"]:
|
||||
continue
|
||||
parts = f.split('.')
|
||||
if len(parts) == 2 and parts[1] == "py":
|
||||
add_to_builtins("extensions.%s.templatetags.%s" \
|
||||
% (ext.name, parts[0]))
|
||||
module = __import__(ext.name, globals(), locals(), ['main'])
|
||||
module.main.init()
|
||||
globals()['extensions'][ext] = module
|
||||
|
||||
def loadmenus():
|
||||
basedir = "%s/extensions" % settings.MAILNG_DIR
|
||||
result = []
|
||||
for name, mod in extensions.iteritems():
|
||||
u = mod.main.urls()
|
||||
for f in os.listdir(basedir):
|
||||
if not os.path.isdir("%s/%s" % (basedir, f)):
|
||||
continue
|
||||
if not isenabled(f):
|
||||
continue
|
||||
module = __import__(f, globals(), locals(), ['main'])
|
||||
module.main.init()
|
||||
u = module.main.urls()
|
||||
if u == ():
|
||||
continue
|
||||
result += (u,)
|
||||
result += [u]
|
||||
return result
|
||||
|
||||
def isenabled(ext):
|
||||
return extensions.has_key(ext)
|
||||
|
||||
def list_extensions():
|
||||
basedir = "extensions"
|
||||
result = []
|
||||
for d in os.listdir(basedir):
|
||||
if not os.path.isdir("%s/%s" % (basedir, d)):
|
||||
continue
|
||||
isvalid = True
|
||||
for f in ['urls.py', 'main.py', '__init__.py']:
|
||||
if not os.path.exists("%s/%s/%s" % (basedir, d, f)):
|
||||
isvalid = False
|
||||
break
|
||||
if isvalid:
|
||||
module = __import__(d, globals(), locals(), ['main'])
|
||||
try:
|
||||
infos = module.main.infos()
|
||||
infos["id"] = d
|
||||
if os.path.isdir("%s/%s/templates" % (basedir, d)):
|
||||
infos["templates"] = True
|
||||
else:
|
||||
infos["templates"] = False
|
||||
result += [infos]
|
||||
except AttributeError:
|
||||
pass
|
||||
return result
|
||||
return "mailng.extensions.%s" % ext in settings.INSTALLED_APPS
|
||||
|
||||
@@ -44,7 +44,7 @@ def menu(**kwargs):
|
||||
return [
|
||||
{"name" : "quarantine",
|
||||
"label" : _("Quarantine"),
|
||||
"url" : reverse(views.index),
|
||||
"url" : reverse(views.index, urlconf='mailng.extensions.amavis_quarantine.exturls'),
|
||||
"img" : "/static/pics/quarantine.png"}
|
||||
]
|
||||
return []
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
extpatterns = [
|
||||
(r'^$', 'index'),
|
||||
(r'^listing/$', '_listing'),
|
||||
(r'^getmailcontent/(?P<mail_id>[\w\-\+]+)/$', 'getmailcontent'),
|
||||
(r'^(?P<mail_id>[\w\-\+]+)/headers/$', 'viewheaders'),
|
||||
(r'^process/$', 'process'),
|
||||
(r'^delete/(?P<mail_id>[\w\-\+]+)/$', 'delete'),
|
||||
(r'^release/(?P<mail_id>[\w\-\+]+)/$', 'release'),
|
||||
(r'^(?P<mail_id>[\w\-\+]+)/$', 'viewmail')
|
||||
]
|
||||
|
||||
urlpatterns = patterns('mailng.extensions.amavis_quarantine.views',
|
||||
(r'^$', 'index'),
|
||||
(r'^listing/$', '_listing'),
|
||||
(r'^getmailcontent/(?P<mail_id>[\w\-\+]+)/$', 'getmailcontent'),
|
||||
(r'^(?P<mail_id>[\w\-\+]+)/headers/$', 'viewheaders'),
|
||||
(r'^process/$', 'process'),
|
||||
(r'^delete/(?P<mail_id>[\w\-\+]+)/$', 'delete'),
|
||||
(r'^release/(?P<mail_id>[\w\-\+]+)/$', 'release'),
|
||||
(r'^(?P<mail_id>[\w\-\+]+)/$', 'viewmail'),
|
||||
*extpatterns
|
||||
)
|
||||
|
||||
@@ -46,7 +46,7 @@ def menu(**kwargs):
|
||||
return [
|
||||
{"name" : "webmail",
|
||||
"label" : _("Webmail"),
|
||||
"url" : reverse(views.index),
|
||||
"url" : reverse(views.index, urlconf='mailng.urls'),
|
||||
"img" : "/static/pics/webmail.png"}
|
||||
]
|
||||
|
||||
|
||||
@@ -63,3 +63,4 @@ class Singleton(type):
|
||||
if cls.instance is None:
|
||||
cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
|
||||
return cls.instance
|
||||
|
||||
|
||||
+6
-2
@@ -24,7 +24,8 @@ def register(event, callback):
|
||||
return 0
|
||||
if not event in callbacks.keys():
|
||||
callbacks[event] = []
|
||||
callbacks[event].append(callback)
|
||||
if not callback in callbacks[event]:
|
||||
callbacks[event].append(callback)
|
||||
return 1
|
||||
|
||||
def unregister(event, callback):
|
||||
@@ -32,7 +33,10 @@ def unregister(event, callback):
|
||||
return False
|
||||
if not callbacks.has_key(event):
|
||||
return False
|
||||
callbacks[event].remove(callback)
|
||||
try:
|
||||
callbacks[event].remove(callback)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
def raiseEvent(event, **kwargs):
|
||||
if not event in events or not event in callbacks.keys():
|
||||
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import os, sys
|
||||
from django.conf import settings
|
||||
|
||||
def usage():
|
||||
print "Usage: extension.py <ext name> <on|off>"
|
||||
sys.exit(1)
|
||||
|
||||
def update_extension(name, extdir, state):
|
||||
for d in ['templates', 'scripts']:
|
||||
if not os.path.isdir("%s/%s" % (extdir, d)):
|
||||
continue
|
||||
cmd = state == "on" \
|
||||
and "ln -s %s/%s %s/%s" % (extdir, d, d, name) \
|
||||
or "rm %s/%s" % (d, name)
|
||||
os.system(cmd)
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 3:
|
||||
usage()
|
||||
extdir = "%s/extensions/%s" % (settings.MAILNG_DIR, sys.argv[1])
|
||||
if not os.path.isdir(extdir):
|
||||
print "Extension not found"
|
||||
sys.exit(1)
|
||||
extname = "mailng.extensions.%s" % sys.argv[1]
|
||||
update_extension(sys.argv[1], extdir, sys.argv[2])
|
||||
if sys.argv[2] == "on":
|
||||
print "Make sure you have added '%s' to INSTALLED_APPS (inside settings.py)" % extname
|
||||
elif sys.argv[2] == "off":
|
||||
print "Make sure you have remove '%s' from INSTALLED_APPS (inside settings.py)" % extname
|
||||
|
||||
+4
-5
@@ -68,11 +68,13 @@ MIDDLEWARE_CLASSES = (
|
||||
|
||||
ROOT_URLCONF = 'mailng.urls'
|
||||
|
||||
MAILNG_DIR = os.path.dirname(__file__)
|
||||
STATIC_ROOTDIR = os.path.join(MAILNG_DIR, 'static')
|
||||
TEMPLATE_DIRS = (
|
||||
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
|
||||
# Always use forward slashes, even on Windows.
|
||||
# Don't forget to use absolute paths, not relative paths.
|
||||
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
|
||||
os.path.join(os.path.dirname(__file__), 'templates'),
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
@@ -82,7 +84,7 @@ INSTALLED_APPS = (
|
||||
'django.contrib.sites',
|
||||
'mailng.lib',
|
||||
'mailng.admin',
|
||||
'mailng.main'
|
||||
'mailng.main',
|
||||
|
||||
# MailNG extensions here.
|
||||
# 'mailng.extensions.postfix_autoreply'
|
||||
@@ -93,6 +95,3 @@ AUTHENTICATION_BACKENDS = (
|
||||
'mailng.lib.authbackends.SimpleBackend'
|
||||
)
|
||||
|
||||
# Autoreplies sending timeout (default: 86400s)
|
||||
# AUTOREPLIES_TIMEOUT =
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
{% extends "admin/settings_header.html" %}
|
||||
{% block menu %}
|
||||
{% load admin_extras %}
|
||||
{% settings_menu "extensions" user %}
|
||||
{% endblock %}
|
||||
{% block setcontent %}
|
||||
{% load i18n %}
|
||||
<form method="POST" action="{% url admin.views.saveextensions %}">
|
||||
{{ extensions }}
|
||||
<br />
|
||||
<input type="submit" name="apply" value="{% trans "Apply" %}" />
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -5,9 +5,8 @@ from django.conf import settings
|
||||
# from django.contrib import admin
|
||||
# admin.autodiscover()
|
||||
|
||||
from mailng.extensions import loadextensions, loadmenus, isenabled
|
||||
from mailng.extensions import *
|
||||
from mailng.lib import parameters
|
||||
loadextensions()
|
||||
|
||||
urlpatterns = patterns('',
|
||||
# Example:
|
||||
@@ -25,12 +24,10 @@ urlpatterns = patterns('',
|
||||
(r'^accounts/login/$', 'mailng.auth.views.dologin'),
|
||||
(r'^accounts/logout/$', 'django.contrib.auth.views.logout_then_login'),
|
||||
(r'^jsi18n/$', 'django.views.i18n.javascript_catalog',
|
||||
{'packages': ('mailng',),})
|
||||
)
|
||||
{'packages': ('mailng',),}),
|
||||
|
||||
menus = loadmenus()
|
||||
if menus != ():
|
||||
urlpatterns += patterns('', *menus)
|
||||
*loadextensions()
|
||||
)
|
||||
|
||||
if settings.DEBUG:
|
||||
urlpatterns += patterns(
|
||||
|
||||
Reference in New Issue
Block a user