Ticket #32 + minor CSS modifications.

This commit is contained in:
tonio
2010-02-05 19:07:51 +01:00
parent f29cb1a342
commit 9ef5df3d26
14 changed files with 117 additions and 36 deletions
+16 -5
View File
@@ -90,19 +90,30 @@ def loadadminextmenu(perms):
@register.simple_tag
def param(app, definition):
print definition
result = """<div class='row'>
<label>%s</label>""" % definition["name"]
name = "%s.%s" % (app, definition["name"])
if definition["type"] in ["string", "int"]:
value = definition.has_key("value") \
and definition["value"] or definition["default"]
name = "%s.%s" % (app, definition["name"])
result += """
<input type='text' name='%s' id='%s' value='%s' />""" % (name, name, value)
if definition["type"] in ["list"]:
if definition["type"] in ["list", "list_yesno"]:
result += """
<select name='' id=''>"""
<select name='%s' id='%s'>""" % (name, name)
values = []
if definition["type"] == "list_yesno":
values = [("yes", _("Yes")), ("no", _("No"))]
else:
if definition.has_key("values"):
values = definition["values"]
value = definition.has_key("value") \
and definition["value"] or definition["default"]
for v in values:
selected = ""
if value == v[0]:
selected = " selected='selected'"
result += "<option value='%s'%s>%s</option>\n" % (v[0], selected, v[1])
result += """
</select>
"""
+3 -1
View File
@@ -413,8 +413,10 @@ def viewparameters(request):
for app in apps:
tmp = {"name" : app, "params" : []}
for p in sorted(parameters._params[app]):
tmp["params"] += [{"name" : p, "value" : parameters.get(app, p),
tmp["params"] += [{"name" : p,
"value" : parameters.get(app, p),
"help" : parameters._params[app][p]["help"],
"default" : parameters._params[app][p]["default"],
"type" : parameters._params[app][p]["type"]}]
gparams += [tmp]
+29 -8
View File
@@ -3,6 +3,7 @@
import re
import time
import imaplib
import ssl
from datetime import datetime, timedelta
from email.header import decode_header
import email.utils
@@ -69,7 +70,10 @@ class IMAPheader(object):
@staticmethod
def parse_date(value):
ndate = datetime(*(email.utils.parsedate_tz(value))[:7])
tmp = email.utils.parsedate_tz(value)
if not tmp:
return value
ndate = datetime(*(tmp)[:7])
now = datetime.now()
if now - ndate > timedelta(7):
return ndate.strftime("%d.%m.%Y %H:%M")
@@ -90,22 +94,30 @@ class IMAPconnector(object):
def __init__(self, request=None, user=None, password=None):
self.address = parameters.get("webmail", "IMAP_SERVER")
self.port = int(parameters.get("webmail", "IMAP_PORT"))
if request:
status, msg = self.login(request.user.username,
request.session["password"])
else:
status, msg = self.login(user, password)
if not status:
# Gestion d'erreur
pass
raise Exception(msg)
def login(self, user, passwd):
import imaplib
try:
self.m = imaplib.IMAP4_SSL(self.address)
secured = parameters.get("webmail", "IMAP_SECURED")
if secured == "yes":
self.m = imaplib.IMAP4_SSL(self.address, self.port)
else:
self.m = imaplib.IMAP4(self.address, self.port)
except (imaplib.IMAP4.error, ssl.SSLError), error:
return False, _("Connection to IMAP server failed, check your configuration")
try:
self.m.login(user, passwd)
except imaplib.IMAP4.error, test:
return False, test
except (imaplib.IMAP4.error, ssl.SSLError), error:
return False, _("Authentication failed, check your configuration")
return True, None
def _encodefolder(self, folder):
@@ -113,9 +125,18 @@ class IMAPconnector(object):
return "INBOX"
return folder.encode("imap4-utf-7")
def messages_count(self, folder=None):
def messages_count(self, folder=None, order=None):
if order:
sign = order[:1]
criterion = order[1:].upper()
if sign == '-':
criterion = "REVERSE %s" % criterion
else:
criterion = "REVERSE DATE"
print criterion
(status, data) = self.m.select(self._encodefolder(folder))
(status, data) = self.m.sort("(REVERSE DATE)", "UTF-8", "(NOT DELETED)")
(status, data) = self.m.sort("(%s)" % criterion, "UTF-8", "(NOT DELETED)")
self.messages = data[0].split()
return len(self.messages)
+9 -5
View File
@@ -9,7 +9,7 @@ from django.core.urlresolvers import reverse
from django.conf.urls.defaults import include
from django.contrib.auth.decorators import login_required
from mailng.admin.models import Mailbox
from mailng.lib import events, parameters, _render
from mailng.lib import events, parameters, _render, _render_error
from mailng.lib.email_listing import Email
from imap_listing import *
from forms import *
@@ -20,7 +20,7 @@ def init():
events.register("UserLogin", userlogin)
parameters.register("webmail", "IMAP_SERVER", "string", "127.0.0.1",
help=_("Address of your IMAP server"))
parameters.register("webmail", "IMAP_SECURED", "list", "No",
parameters.register("webmail", "IMAP_SECURED", "list_yesno", "no",
help=_("Use a secure connexion to access IMAP server"))
parameters.register("webmail", "IMAP_PORT", "int", "143",
help=_("Listening port of your IMAP server"))
@@ -60,8 +60,9 @@ def folder(request, name, updatenav=True):
pageid = request.GET.has_key("page") and int(request.GET["page"]) or 1
request.session["folder"] = name
request.session["page"] = pageid
order = request.GET.has_key("order") and request.GET["order"] or None
lst = ImapListing(request.user.username, request.session["password"],
name, folder=name)
name, folder=name, order=order)
page = lst.paginator.getpage(request.session["page"])
if page:
content = lst.fetch(request, page.id_start, page.id_stop)
@@ -75,8 +76,11 @@ def folder(request, name, updatenav=True):
@login_required
def index(request):
lst = ImapListing(request.user.username, request.session["password"],
"INBOX", folder="INBOX")
try:
lst = ImapListing(request.user.username, request.session["password"],
"INBOX", folder="INBOX")
except Exception as exp:
return _render_error(request, {"error" : exp})
return lst.render(request, empty=True)
def fetchmail(request, folder, mail_id, all=False):
+26 -4
View File
@@ -207,6 +207,32 @@ tr {
});
});
$$("tr").addEvent("dblclick", viewmail);
var sortOrder = "";
$$("th[class=sortable]").addEvent("click", function(evt) {
var tmp = "?";
if (sortOrder == "") {
test = /order=([\+\-]\w+$|&)/.exec(location.hash);
if (test) {
sortOrder = test[1];
}
}
if (sortOrder.substring(1) == evt.target.id) {
var sign = (sortOrder.charAt(0) == '+') ? '-' : '+';
sortOrder = sign + evt.target.id;
} else {
sortOrder = "-" + evt.target.id;
}
if (location.hash.indexOf("?") != -1) {
if (location.hash.indexOf("order") != -1) {
location.hash = location.hash.replace(/order=[\+\-]\w+$|&/,
"order=" + sortOrder);
return;
}
tmp = "&";
}
location.hash += tmp + "order=" + sortOrder;
});
});
navbarcallback = function(event) {
@@ -224,10 +250,6 @@ tr {
$$("a[name=compose]").addEvent("click", loadCompose);
{% endblock %}
{% block middletitle %}{% trans "Webmail" %}{% endblock %}
{% block menu %}
{% load webextras %}
{% listing_menu "" "INBOX" perms %}
{% endblock %}
{% block leftcol %}
<div id="leftcol" class="box">
<h3>{% trans "Folders" %}</h3>
+4
View File
@@ -50,6 +50,10 @@ def _render(request, tpl, user_context):
return render_to_response(tpl, user_context,
context_instance=RequestContext(request))
def _render_error(request, user_context):
return render_to_response("common/error.html", user_context,
context_instance=RequestContext(request))
def exec_as_vuser(cmd):
code, output = exec_pipe("sudo -u %s %s" % (settings.VIRTUAL_UID, cmd))
if code:
+2 -1
View File
@@ -80,7 +80,8 @@ class EmailListing:
def __init__(self, folder=None, elems_per_page=40, **kwargs):
self.folder = folder
self.elems_per_page = elems_per_page
self.paginator = Paginator(self.mbc.messages_count(self.folder),
order = "order" in kwargs.keys() and kwargs["order"] or None
self.paginator = Paginator(self.mbc.messages_count(self.folder, order),
elems_per_page)
def render_navbar(self, page):
+1 -1
View File
@@ -24,7 +24,7 @@ class NotDefined(Exception):
return "Application '%s' and/or parameter '%s' not defined" % (self.app,
self.name)
def register(app, name, type="string", deflt=None, help=None):
def register(app, name, type="string", deflt=None, help=None, **kwargs):
"""Register a new parameter.
app corresponds to a core component (admin, main) or an extension.
+1 -1
View File
@@ -23,7 +23,7 @@ check_anchor = function() {
query = "INBOX/"; // Default location
} else {
var splits = current_anchor.substring(1).split('?');
var section = splits[0];
var section = (splits[0] != "") ? splits[0] : "INBOX";
delete splits[0];
var params = splits.join('&');
if (section[section.length - 1] != '/') {
+1
View File
@@ -66,6 +66,7 @@ window.addEvent('domready', function() {
}
}
});
setDivHeight("content", 20, 0);
});
newdom = function() {
+1
View File
@@ -3,6 +3,7 @@ window.addEvent('domready', function() {
parse: 'rel',
});
setDivHeight("content", 20, 0);
if ($$("a[name=deletePerm]"))
$$("a[name=deletePerm]").addEvent('click', function(event) {
+17 -9
View File
@@ -262,16 +262,13 @@ table.hr {
}
.toggler {
color: #222;
margin: 0;
margin: 5px auto;
padding: 2px 5px;
background: #eee;
border-bottom: 1px solid #ddd;
border-right: 1px solid #ddd;
border-top: 1px solid #f5f5f5;
border-left: 1px solid #f5f5f5;
font-size: small;
font-weight: normal;
background: #CEDBEC;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
/*border: 1px solid #CCC;*/
font-size: 1.1em;
}
.element {
@@ -287,3 +284,14 @@ div.row label {
width: 200px;
padding: 3px 0;
}
.error {
margin: 0 auto;
padding: 5px;
background: red;
width: 500px;
text-align: center;
background-color: #F9D2D2;
border: 3px solid #FF2A2A;
color: #FF2A00;
}
+6
View File
@@ -0,0 +1,6 @@
{% extends "nlayout.html" %}
{% load i18n %}
{% block middletitle %}{% trans "Error" %}{% endblock %}
{% block content %}
<div class="error"><p>{{ error }}</p></div>
{% endblock %}
+1 -1
View File
@@ -2,7 +2,7 @@
<thead>
<tr>
{% for c in table.columns %}
<th width="{{ c.width }}">{{ c|safe }}</th>
<th id="{{ c.name }}" class="sortable" width="{{ c.width }}">{{ c|safe }}</th>
{% endfor %}
</tr>
</thead>